📄 example
字号:
char *p = 0; opterr = 0; while (1) { int option_index = 0; static struct option long_options[] = { {"host", 1, 0, 0}, {"port", 1, 0, 0}, {"back", 1, 0, 0}, {"dir", 1, 0, 0}, {"log", 1, 0, 0}, {"daemon", 0, 0, 0}, {0, 0, 0, 0} }; /* 本程序支持如一些参数: * --host IP地址 或者 -H IP地址 * --port 端口 或者 -P 端口 * --back 监听数量 或者 -B 监听数量 * --dir 网站根目录 或者 -D 网站根目录 * --log 日志存放路径 或者 -L 日志存放路径 * --daemon 使程序进入后台运行模式 */ c = getopt_long(argc, argv, "H:P:B:D:L", long_options, &option_index); if (c == -1 || c == '?') break; if(optarg) len = strlen(optarg); else len = 0; if ((!c && !(strcasecmp(long_options[option_index].name, "host"))) || c == 'H') p = host = malloc(len + 1); else if ((!c && !(strcasecmp(long_options[option_index].name, "port"))) || c == 'P') p = port = malloc(len + 1); else if ((!c && !(strcasecmp(long_options[option_index].name, "back"))) || c == 'B') p = back = malloc(len + 1); else if ((!c && !(strcasecmp(long_options[option_index].name, "dir"))) || c == 'D') p = dirroot = malloc(len + 1); else if ((!c && !(strcasecmp(long_options[option_index].name, "log"))) || c == 'L') p = logdir = malloc(len + 1); else if ((!c && !(strcasecmp (long_options[option_index].name, "daemon")))) { daemon_y_n = 1; continue; } else break; bzero(p, len + 1); memcpy(p, optarg, len); }}int main(int argc, char **argv){ struct sockaddr_in addr; int sock_fd, addrlen; /* 获得程序工作的参数,如 IP 、端口、监听数、网页根目录、目录存放位置等 */ getoption(argc, argv); if (!host) { addrlen = strlen(DEFAULTIP); AllocateMemory(&host, addrlen, DEFAULTIP); } if (!port) { addrlen = strlen(DEFAULTPORT); AllocateMemory(&port, addrlen, DEFAULTPORT); } if (!back) { addrlen = strlen(DEFAULTBACK); AllocateMemory(&back, addrlen, DEFAULTBACK); } if (!dirroot) { addrlen = strlen(DEFAULTDIR); AllocateMemory(&dirroot, addrlen, DEFAULTDIR); } if (!logdir) { addrlen = strlen(DEFAULTLOG); AllocateMemory(&logdir, addrlen, DEFAULTLOG); } printf ("host=%s port=%s back=%s dirroot=%s logdir=%s %s是后台工作模式(进程ID:%d)\n", host, port, back, dirroot, logdir, daemon_y_n?"":"不", getpid()); /* fork() 两次处于后台工作模式下 */ if (daemon_y_n) { if (fork()) exit(0); if (fork()) exit(0); close(0), close(1), close(2); logfp = fopen(logdir, "a+"); if (!logfp) exit(0); } /* 处理子进程退出以免产生僵尸进程 */ signal(SIGCHLD, SIG_IGN); /* 创建 socket */ if ((sock_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { if (!daemon_y_n) { prterrmsg("socket()"); } else { wrterrmsg("socket()"); } } /* 设置端口快速重用 */ addrlen = 1; setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &addrlen, sizeof(addrlen)); addr.sin_family = AF_INET; addr.sin_port = htons(atoi(port)); addr.sin_addr.s_addr = inet_addr(host); addrlen = sizeof(struct sockaddr_in); /* 绑定地址、端口等信息 */ if (bind(sock_fd, (struct sockaddr *) &addr, addrlen) < 0) { if (!daemon_y_n) { prterrmsg("bind()"); } else { wrterrmsg("bind()"); } } /* 开启临听 */ if (listen(sock_fd, atoi(back)) < 0) { if (!daemon_y_n) { prterrmsg("listen()"); } else { wrterrmsg("listen()"); } } while (1) { int len; int new_fd; addrlen = sizeof(struct sockaddr_in); /* 接受新连接请求 */ new_fd = accept(sock_fd, (struct sockaddr *) &addr, &addrlen); if (new_fd < 0) { if (!daemon_y_n) { prterrmsg("accept()"); } else { wrterrmsg("accept()"); } break; } bzero(buffer, MAXBUF + 1); sprintf(buffer, "连接来自于: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); if (!daemon_y_n) { prtinfomsg(buffer); } else { wrtinfomsg(buffer); } /* 产生一个子进程去处理请求,当前进程继续等待新的连接到来 */ if (!fork()) { bzero(buffer, MAXBUF + 1); if ((len = recv(new_fd, buffer, MAXBUF, 0)) > 0) { FILE *ClientFP = fdopen(new_fd, "w"); if (ClientFP == NULL) { if (!daemon_y_n) { prterrmsg("fdopen()"); } else { prterrmsg("fdopen()"); } } else { char Req[MAXPATH + 1] = ""; sscanf(buffer, "GET %s HTTP", Req); bzero(buffer, MAXBUF + 1); sprintf(buffer, "请求取文件: \"%s\"\n", Req); if (!daemon_y_n) { prtinfomsg(buffer); } else { wrtinfomsg(buffer); } /* 处理用户请求 */ GiveResponse(ClientFP, Req); fclose(ClientFP); } } exit(0); } close(new_fd); } close(sock_fd); return 0;}[/code]编译程序用下列命令:gcc -Wall das-server.c -o das-server注:das即 Dictory Access Server以root用户启动服务程序用下列命令:./das-server或以普通用户启动服务程序用下列命令:./das-server --port 7838或./das-server -P 7838注:只有root用户才有权限启动1024以下的端口,所以如果想用默认的80端口就得用root来运行。如果要想让程序在后台自动运行,即处理精灵模式下工作,在命令后面加上--daemon参数即可。打开一个网络浏览器输入服务地址开始浏览,如下图:[img]http://zhoulifa.bokee.com/inc/dasserver.png[/img]下载文件如下图:[img]http://zhoulifa.bokee.com/inc/dassave.png[/img]注:请不要下载较大的文件,比如文件大小超过10M的,因为程序是一次分配内存,会占用系统内存较大导致系统死掉!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -