0

サーフィン中に画像をキャッシュするために使用されるローカルマシンでプロキシサーバーを実行しています。プロキシを使用してブラウザを127.0.0.1に設定し、HTTPリクエストを受信し、データを取得してブラウザに送り返します。大きな画像を除くすべての場合に正常に機能します。画像情報を受け取ると、画像の半分(例:グーグルロゴの上半分)だけが表示されます。コードは次のとおりです。

  char buffer[1024] = "";
    string ret("");
    while(true)
    {
        valeurRetour = recv(socketClient_, buffer, sizeof(buffer), 0);
        if(valeurRetour <= 0) break;
        string t;
        t.assign(buffer,valeurRetour);
        ret += t;
        longueur += valeurRetour;
    }
    closesocket(socketClient_);
    valeurRetour = send(socketServeur_, ret.c_str(),longueur, 0);

socketClient_は非ブロッキングです。この問題を解決する方法はありますか?

4

2 に答える 2

2

の可能な戻り値を十分に区別していませんrecv

ここには2つのレベルがあります。

1つ目は、0と-1をひとまとめにしているということです。0は、リモートピアが接続の送信の半分を閉じたことを意味します。したがって、コードはここで正しいことを行い、ソケットも閉じます。-1は、受信中のデータ以外に何かが発生したことを意味します。これは、永続的なエラー、一時的なエラー、またはデータの受信以外に何かが発生したというスタックからの単なる通知である可能性があります。コードはそのようなすべての可能性をひとまとめにし、その上、リモートピアが接続を閉じたときと同じように扱います。

recv2番目のレベルは、ソケットが役に立たなくなったという意味で、-1を取得するすべての理由が「エラー」であるとは限らないということです。WSAGetLastError-1をチェックしてから、-1を取得した理由を調べるために呼び出しを開始すると、が取得されると思いますWSAEWOULDBLOCK。これは、非ブロッキングソケットがあるため正常です。これは、recvプログラムの実行スレッドをブロックする必要があるため、呼び出しがデータを返すことができないことを意味し、Winsockに非ブロック呼び出しが必要であることを伝えました。

素朴な修正は、ループから抜け出さないことですが、それは、データが返されるまで、WSAEWOULDBLOCKCPU時間を何度も何度も呼び出すことを意味します。recvこれは、ネットワークがビジー状態のときにプログラムが他のことを実行できるようにする、非ブロッキングソケットの全体的なポイントに反します。のような関数を使用するかselect、API関数の呼び出しが再び成功する可能性が高いときに通知を受けることになっています。それまでは、あなたはそれを呼ばないでください。WSAAsyncSelectWSAEventSelect

WinsockプログラマーのFAQにアクセスすることをお勧めします。(免責事項:私はそのメンテナです。)

于 2009-11-22T15:07:25.517 に答える
0

HTTPレベルでトランザクションを分析しましたか、つまりヘッダーをチェックしましたか?

チャンク転送などを考慮していますか?

ここに詳細が記載されていないため、明確な答えはありません。

于 2009-11-22T11:56:39.800 に答える