8

組み込みデバイスの HTTP デーモンに対して HttpWebRequest を使用すると問題が発生します。問題は、ソケット ストリームに書き込まれる http ヘッダーと http ペイロード (POST) の間に十分な遅延があるため、ソケットがソケット バッファーの内容をサーバーに解放することです。これにより、HTTP 要求が 2 つのパケットに分割されます (フラグメンテーション)。

もちろん、これは完全に有効ですが、パケットが約 1.8 ミリ秒以上分割されている場合、相手側のサーバーはそれに対処できません。したがって、これを(クライアントで)制御する現実的な方法があるかどうか疑問に思っています。

送信に使用されるソケットをこのレベルで制御する HttpWebRequest のプロパティはないようです。また、送信中にのみ作成されるため、ソケット自体に (つまり、リフレクションを介して) アクセスすることはできません。その後リリースされました (アウトバウンド http 接続プーリングの一部として)。BufferWriteStream プロパティは、webrequest 内の本文コンテンツをバッファリングするだけで (したがって、リダイレクトなどに引き続き使用できます)、リクエスト全体がソケットに書き込まれる方法には影響を与えないようです。

じゃあ何をすればいいの?

(ソケットから HTTP クライアントを書き直す必要がないように本当に努めています)

1 つのオプションは、HttpWebRequest が (おそらく ServicePoint を介して) 送信する何らかの種類のプロキシを記述し、その実装で TCP 要求全体をバッファリングすることです。しかし、それは大変な作業のようです。

Fidder を実行しているときも (同じ理由で) 正常に動作しますが、それは実稼働環境では実際にはオプションではありません...

[ps: NoDelay ソケットを使用してフラグメント化を明示的に制御するソケットレベルのテストをノックアップしたため、フラグメント化されたパケット間の間隔が問題であることは間違いありません]

4

4 に答える 4

2

最終的に、ベンダーは新しいバージョンの HTTPD を含むファームウェア アップグレードをプッシュし、問題は解消されました。彼らは BusyBox Linux を使用していましたが、どうやら HTTPD の実装に別の問題があり、彼らが苦しんでいたようです。

私の最初の質問に関しては、ソケットプロキシを作成する以外に、信頼できる方法はないと思います。上記で試した回避策のいくつかは、設計ではなく運によって機能しました (.net がパケット全体を一度に送信することを意味していたため)。

于 2011-03-24T09:05:36.627 に答える
1

組み込みサーバーは HTTP/1.1 サーバーですか? その場合は、GetRequestStream() を呼び出す前に、webrequest で Expect100Continue=false を設定してみてください。これにより、エンティティ本体を送信する前に、HTTP スタックがサーバーからの「HTTP/1.1 100 continue」ヘッダー応答を予期しないことが保証されます。そのため、パケットはヘッダーとボディの間で分割されますが、パケット間のギャップは短くなります。

于 2010-02-05T14:21:12.470 に答える
0

クライアント側のパケット分割の問題を見るだけで、これにリンクされている自分の質問に対する回答を投稿しました。

私はここで答えを見ました:

http://us.generation-nt.com/answer/too-packets-httpwebrequest-help-23298102.html

于 2012-11-13T16:50:41.470 に答える