⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 example

📁 简单的http服务器
💻
📖 第 1 页 / 共 2 页
字号:
    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 + -