0

Webdis に基づいて単純な HTTP サーバーを作成しました。ここで、クライアントが応答を受信せずに HTTP 要求を送信している間 (別名、送信のみで、サーバーからの応答を受信しない)、サーバーが複数の HTTP 要求を受信し、これにより解析モジュールが失敗するという問題が発生しました (これはおそらく解析モジュールのバグ)。あいまいな場合は、私のコードの一部を以下に示します。

/* client... */
int fd = connect_server();
while (1) {
    send(fd, buf, sz);
    continue; /* no receive.. */        
}

/* server... */
/* some event trigger following code */
char buffer[4096]; /* a stack based receive buffer, buggy */
ret = recv(fd, buffer, sizeof(buffer));

クライアントがサーバーのスリープ中 (デバッグ用) に 10 個の HTTP 要求 (4096 バイト未満) を送信している間、これは次の受信で 10 個の要求を一度に受信しますが、パーサーは複数の要求を解析できないため、これらすべての要求が失敗します。これらすべてが 4096 よりも大きいリクエストを行った場合、そのうちの 1 つが切断され、それでも失敗します。

私はNginxのソースコードを閲覧しましたが、コールバックが設計されている可能性があります(非難ではありません)が、その解決策はありません...


次のことを行う方法はありますか?

recv一度に 1 つの要求しか受信しない呼び出しを制御する方法は? sendそれとも、リクエストを 1 つだけ受信できるようにする TCP 関連のメカニズムはありますか?

4

2 に答える 2

1

TCP は定義上ストリームベースであるため、メッセージの境界線が変更されることは保証されません。厳密に言えば、そのようなものは TCP には存在しません。ただし、ブロッキング ソケットを使用し、Nagle のアルゴリズムが無効になっていることを確認すると、各 recv() に複数のセグメントが含まれる可能性が低くなります。テストのために、各 send() の後にスリープを挿入することもできます。TCP_CORK をいじることもできます。

ただし、何かを一緒にハッキングする代わりに、ある時点でそれを行う必要があるため、「適切に」受信を実装することをお勧めします。recv-call ごとに、バッファーに HTTP 要求 (\r\n\r\n) の末尾が含まれているかどうかを確認してから処理します。

于 2013-05-28T06:01:58.603 に答える