HTTPサーバがレスポンスを返さない


Cで書いたHTTPサーバーがレスポンスを返しません  
何が原因なのでしょうか?

原因として考えられるのは、`recv`は何もデータが来なければブロックするようなので、そこで動作が止まってしまい、サーバーがデータを送信できなくなっているのでしょうか?

[code]

    #include <stdio.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <inttypes.h>
    #include <string.h>
    #include <errno.h>
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    
    int main() {
        int64_t MSG_BUF_SIZE = 4000;
    
        int sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock == -1) {
            perror("Socket creation error");
        }
        struct sockaddr_in server_addr;
        memset(&server_addr, 0, sizeof(server_addr));
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(3211);
        server_addr.sin_addr.s_addr = INADDR_ANY;
    
        if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
            perror("Bind Error");
            return EXIT_FAILURE;
        }
    
        if (listen(sock, 11) != 0) {
            perror("Listen Error");
            return EXIT_FAILURE;
        }
    
        char send_message_buf[4096];
        memset(send_message_buf, 0, sizeof(send_message_buf));
        snprintf(send_message_buf, sizeof(send_message_buf), "HTTP/1.0 200 OK\r\n"
         "Content-Length: 20\r\n"
         "Content-Type: text/html\r\n"
         "\r\n"
         "HELLO\r\n");
    
        while (true) {
            struct sockaddr_in client;
            memset(&client, 0, sizeof(client));
            int accept_sock = accept(sock, (struct sockaddr *)&client, (socklen_t *)&client);
            if (accept_sock == -1) {
                perror("Accept Error");
                return EXIT_FAILURE;
            }
            char read_buf[3000];
            size_t read_length = 0;
            char *msg_buf = calloc(MSG_BUF_SIZE, sizeof(char));
            ssize_t r;
            memset(read_buf, 0, sizeof(read_buf));
            while ((r = recv(accept_sock, read_buf, sizeof(read_buf), 0)) > 0) { // ここでブロックしている?
                printf("r = %zd\n", r);
                if (read_length + r > MSG_BUF_SIZE - 1) {
                    MSG_BUF_SIZE *= 2;
                    msg_buf = realloc(msg_buf, (MSG_BUF_SIZE + 1) * sizeof(char));
                }
                memmove(msg_buf + read_length, read_buf, r);
                read_length += r;
            }
    
            if (r == 0) {
                msg_buf = strcat(msg_buf, "");
                printf("%s\n", msg_buf);
            }
            else if(r == -1) {
                perror("recv Error");
                return EXIT_FAILURE;
            }
    
            free(msg_buf);
            if (send(accept_sock, send_message_buf, strlen(send_message_buf), 0) == -1) {
                perror("Send Error");
            }
        }
    }
    
[/code]




HTTPはバージョン1.1よりPersistent
Connectionsがデフォルトとなっています。そこでHTTP/1.1に対応したWebブラウザーではブラウザー側からコネクションを切断することはありません。そのためサーバー側の

>
[code]

>     while ((r = recv(accept_sock, read_buf, sizeof(read_buf), 0)) > 0) { //
> ここでブロックしている?
>  
[/code]

が完了することはありません。読み取れたところまでで中断し、リクエストヘッダーを解析する処理に移る必要があります。




HTTPはバージョン1.1よりPersistent
Connectionsがデフォルトとなっています。そこでHTTP/1.1に対応したWebブラウザーではブラウザー側からコネクションを切断することはありません。そのためサーバー側の

>
[code]

>     while ((r = recv(accept_sock, read_buf, sizeof(read_buf), 0)) > 0) { //
> ここでブロックしている?
>  
[/code]

が完了することはありません。読み取れたところまでで中断し、リクエストヘッダーを解析する処理に移る必要があります。

