套接字服务器中的c-Keep-alive属性

时间:2017-11-17 13:04:25

标签: c linux sockets

我必须在linux上的套接字上的http服务器中实现keep-alive属性。这是读取,解析请求和发送响应的函数代码。

static void *parse_request(void *ptr)
{
    struct parse_arg *arg = (struct parse_arg *) ptr;
    char buf[MAX_MSG];
    ssize_t bytes_read;
    char *msg;
    char version[MAX_MSG];
    int is_implemented = 0;
    int result;

    //Wait until the socket will be ready to read data
    do {
        fd_set readfds;
        struct timeval tv = { };

        tv.tv_sec = TIMEOUT_SECS;
        FD_ZERO(&readfds);
        FD_SET(arg->sock, &readfds);
        result = select(arg->sock + 1, &readfds, NULL, NULL, &tv);

        //read input data
        if(result > 0) {
            if(FD_ISSET(arg->sock, &readfds)) {
                bytes_read = 
                    read(arg->sock, buf, sizeof(char) * MAX_MSG);
                if (bytes_read == -1) {
                    perror("Error when reading request");
                    return (void *)-1;
                }

                if (bytes_read == 0) {
                    fprintf(stderr, 
                        "Client disconnected unexpectedly\n");
                    close(arg->sock);
                    return (void *)-1;
                }
                msg = buf;
                printf("REQUEST:%s", msg);
                msg[bytes_read] = '\0';

                //parse HTTP method, path to file, HTTP version
                if (msg == strstr(msg, GET))
                    is_implemented = 1;
                msg += strlen(GET) + 1;
                char *path_begin = msg;

                msg = strchr(msg, ' ');
                *msg = '\0';
                ++msg;
                strcpy(arg->c_arg->root, path_begin);
                char *version_begin = msg;

                msg = strstr(msg, "\r\n");
                *msg = '\0';
                strcpy(version, version_begin);
                if (!is_implemented) {
                    not_implemented(arg->sock, version);
                    return (void *)-1;
                }
                int version_check = !strcmp(version, "HTTP/1.0")
                    || !strcmp(version, "HTTP/1.1");
                if (!version_check) {
                    bad_request(arg->sock, version);
                    return (void *)-1;
                }
                serve_request(arg->sock, arg->c_arg, version);
            }
        } else if (result < 0) {
            perror("Error in select");
            return (void *)-1;
        } else {
            close(arg->sock);
        }
    } while (result == -1);

    return (void *)0;
}

我在select()方面遇到了一些问题。当我启动服务器并尝试只打开一个页面时,它不会打开。但是,当我关闭此页面并打开新页面时,它们会打开并且工作得很好。谁能告诉我问题可能在哪里?

0 个答案:

没有答案