1

非常に基本的な HTTP サーバーを作成しようとしています。サーバーとサービスを 2 つの別個の実行可能ファイル (inetd と同様) に分離したいと考えています。

したがって、サービスをフォークし、execを使用してそのコードを実行する汎用サーバーがあります。主なループは次のとおりです。

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);
}

サービスは stdin で読み取り、stdout で書き込み、単純な http 要求を処理します。nc を使用してサーバーに接続すると、すべて正常に動作するようです。nc は、予想される http 応答を受信して​​表示します。

ただし、Webブラウザを使用してサーバーに接続すると、ブラウザはサーバーが接続を突然閉じたことを通知します(ECONNRESETエラーだと思います)。サービスがリクエストを処理したことは確かです。strace を使用してサービスの実行を確認しました。予想される「write(1,...)」はすべてそこにあり、close(1) はありません。さらに驚くべきことに、Web ブラウザーが応答を受け取ることがあります。

提供されたコードに問題があるように見えますか? そうでない場合、何が問題を引き起こす可能性がありますか?

4

1 に答える 1

3

問題はあなたが示したコードではなく、あなたが実行したプログラムにあると思います。典型的な問題は、クライアント (つまり、プログラム) が HTTP ヘッダーを読み取らず、代わりにデータを書き込んで終了することです。この場合、ブラウザへのファイル記述子は閉じられますが、サーバーからの未処理のデータがソケット バッファに残っています。これにより、サーバー OS が RST パケットを送信し、ブラウザで ECONNRESET が発生します。運が良ければ、ブラウザが RST を取得する前に応答を取得してレンダリングしたため、接続リセット エラーが表示される場合と表示されない場合があります。

于 2015-11-25T11:35:18.030 に答える