1

Cソケットを使用してWebサーバーから「大きな」ファイルを受信するのに問題があります。つまり、これらのファイル(または私が疑う)が、それらを受信するために使用しているバッファーのサイズよりも大きい場合です。index.html(GETリクエストを介して)数バイト以下の単純なものを要求しようとすると、問題はありませんが、それ以外は失敗します。私の知識の欠如、select()またはそれrecv()が私を失敗させているものだと思います。ここを参照してください:

fd_set read_fd_set;
FD_ZERO(&read_fd_set);
FD_SET((unsigned int)socketId, &read_fd_set);

/* Initialize the timeout data structure. */
struct timeval timeout;
timeout.tv_sec = 2;
timeout.tv_usec = 0;

// Receives reply from the server
int headerReceived = 0;
do {
    select(socketId+1, &read_fd_set, NULL, NULL, &timeout);

    if (!(FD_ISSET(socketId, &read_fd_set))) {
       break;
    }

    byteSize = recv(socketId, buffer, sizeof buffer, 0);

    if (byteSize == 0 || (byteSize < BUFFER_SIZE && headerReceived)) {
       break;
    }

    headerReceived = 1;

} while(1);

そうです、GETリクエストをWebサーバーに送信した後、サーバーは正常に動作していると確信しており、他のクライアント(Webブラウザーなど)からのGETリクエストは意図したとおりに機能しています。

よろしくお願いします。どんな助けでも大歓迎です。

4

3 に答える 3

2
if (byteSize == 0 || (byteSize < BUFFER_SIZE && headerReceived))
{
    break;
}

headerReceived最初の読み取り後にtrueに設定されます。それは完全に可能であり、おそらく後続recv()のsは。未満になりBUFFER_SIZEます。その時点で読み取りループから外れています。 Recv()読み取るバイト数は何でも返されますが、必ずしも要求したバイト数ではありません。

BUFFER_SIZEまた、またはに固執しsizeof(buffer)ます。ミキシングとマッチングは、将来どこかでバグを求めているだけです。

于 2012-05-21T00:19:46.487 に答える
1

使用しているO/Sについては言及していませんが、POSIX仕様によると:

正常に完了すると、select()関数はtimeout引数が指すオブジェクトを変更する場合があります。

(たとえば、Linuxはまさにこれを実行すると思います。)

したがって、ループを後で呼び出すと、タイムアウトがゼロに設定される可能性が非常に高くなります。これによりselect、記述子が準備できていなくてもすぐに戻ります。

selectループを通過するたびに呼び出す直前に、タイムアウト構造を再初期化することをお勧めします。

于 2012-05-21T00:08:48.470 に答える
1

私が見つけた1つのことは、ループ中に選択を再初期化しないことです。これがおそらく、小さなファイルを正常に取得する理由です。それらは一度に受信され、ループを繰り返す必要はありません。

私はあなたが置くことをお勧めします:

FD_ZERO(&read_fd_set);
FD_SET((unsigned int)socketId, &read_fd_set);
timeout.tv_sec = 2;
timeout.tv_usec = 0;

ループ内(を呼び出す前select)で、正常に機能する可能性があります。

于 2012-05-21T00:27:42.717 に答える