Simple http generic server using fork and dup

2019-08-15 03:47发布

I'm trying to write a very basic HTTP server. I want to separate the server and the service in two separate executable (similar to inetd).

So I have a generic server, that forks a service and execute its code using exec. The main loop is as follows:

while(true) {
    int client_sock;

    if ((client_sock = accept(server_sock, (struct sockaddr *) NULL, NULL)) < 0) {
        return -1;
    } 

    pid_t pid = fork();

    if (pid == 0) {
        close(server_sock);
        close(0);
        dup(client_sock);
        close(1);
        dup(client_sock);
        execvp(argv[2], argv+2);
        return -1;
    } else if (pid < 0) {
       assert(false);
    }
    close(client_sock);
}

The service reads on stdin, and writes on stdout and processes simple http requests. Everything seems to work fine when I connect to my server using nc. nc receives and displays the expected http reply.

However, when I connect to my server using a web browser, the browser tells me that the server closed the connection abruptly (ECONNRESET error I believe). I'm sure that my service processed the request: I checked the execution of my service with strace, all the expected "write(1,...)" are there, and there are not any close(1). Even more surprising, some times, the web browser gets the reply.

Does anything look wrong in the provided code? if not, what could cause the problem?

1条回答
你好瞎i
2楼-- · 2019-08-15 04:24

I guess the problems lies not in the code you have shown, but in the program you exec. A typical problem is that the client (i.e. your program) does not read the HTTP header but instead just writes the data and finishes. In this case the file descriptor to the browser gets closed while there are still unprocessed data from the server in the socket buffer. This causes the server OS to send a RST packet which then causes the ECONNRESET in the browser. If you are lucky the browser got and rendered the response before it got the RST, so you will see the connection reset error sometimes and sometimes not.

查看更多
登录 后发表回答