C 在从套接字写入和读取时退出

C exits when writing and reading from sockets

我正在尝试用 C 编写一个非常基本的 http 服务器,但我看到的一些 C 行为让我感到困惑。据我所知,这段代码应该永远循环(当客户端是 netcat 时它会循环)但是当客户端是浏览器时,它就会退出(呈现“hello world”之后)。

如果它退出时出现错误,那么一切就都说得通了。但它似乎只是愉快地退出而没有任何错误信息!你不能 运行 远离这样的无限 while 循环!

    #include<stdio.h>
    #include<string.h>  //strlen
    #include<sys/socket.h>
    #include<arpa/inet.h>   //inet_addr
    #include<unistd.h>  //write
    #include<stdlib.h>
    
    int main(int argc , char *argv[])
    {
        int socket_desc , new_socket , c;
        struct sockaddr_in server , client;
        char *message;
        char *buffer = "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 12\n\nHello world!";
        //Create socket
        socket_desc = socket(AF_INET , SOCK_STREAM , 0);
        if (socket_desc == -1)
        {
            printf("Could not create socket");
        }
        
        //Prepare the sockaddr_in structure
        server.sin_family = AF_INET;
        server.sin_addr.s_addr = INADDR_ANY;
        server.sin_port = htons( 8888 );
        
        //Bind
        if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
        {
            puts("bind failed");
            return 1;
        }
        puts("bind done");
        
        //Listen
        listen(socket_desc , 3);
        
        //Accept and incoming connection
        puts("Waiting for incoming connections...");
        c = sizeof(struct sockaddr_in);
        int read_size;
        char client_message[2000];
        new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
        while( 1 )
        {
            write(new_socket , buffer , strlen(buffer));
            while (1){ 
                read_size = recv(new_socket , client_message , 2000 , 0);
                //send the exact same message again
                write(new_socket , buffer , strlen(buffer));
            }
        }
        
        if (new_socket<0)
        {
            perror("accept failed");
            return 1;
        }
        
        return 0;
    }
new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t *)&c);
while (1)
{
    write(new_socket, buffer, strlen(buffer));
    while (1)
    {
        read_size = recv(new_socket, client_message, 2000, 0);
        //send the exact same message again
        write(new_socket, buffer, strlen(buffer));
    }
}

您在您的程序中只调用了一次 accept - 即您只会收到一个传入请求。并且您无限地将相同的缓冲区发送回新连接 - 这不是网络通信的工作方式。

您可能想要做的是循环调用 accept 并为每个连接提供缓冲区。

例如:

while (1)
{
    new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t *)&c);
    write(new_socket, buffer, strlen(buffer));
    close(new_socket);
}