使用に同意するものと見なされます。コード提供終了済みコンテンツ申し訳ありません。リクエストされたコンテンツは削除されています。自動的にリダイレクトされます。Studio2015でソケット通信のサーバー側のプログラミングをしてます。実行時間を早くするために、TCP遅延ACKを無効化したいです。ネットにある情報では以下のレジストリを1にする方法が紹介されてます。GUID}\TcpAckFrequencyただ、この方法だと再起動が必要な上に無線アダプタごとに設定しなければならなず、ユーザーから見て使用性が低くなるので、極力レジストリを変更せずにTCP遅延ACKをなくす方法を探しています。プログラムの中でソケットオプションでTCP_NODELAYを設定する方法がありましたが、これでは遅延ACKはなくなりませんでした。TCP_QUICKACKとうのもあるらしいですが、Windowsでは定義されてませんでした。回答ではなく一般論になってしまいます。TCP_NODELAYオプションはNagleを無効化するもので、DelayedACKとの相乗的な遅延に対するある程度の効果が期待できますが、それ自体を無効化するものではありません。当たり前ですがNagleアルゴリズム(RFC896)とDelayedACK(RFC1122)は別物です。次に、これらは標準的に実装されていて、回避することは一般的にはできません。OS自体もこれを前提として実装されていると予測できるため、これらを外した場合、OSの動作が不安定になる可能性を覚悟しなければなりません。従ってピアツーピア接続などの限定的な場合を除いて現実的な選択肢にはなりません。両者の悪い影響を少なくするための傾向と対策的な手法は色々とあるようです。それらを行ってみるべきではないでしょうか。前提として、これらのアルゴリズムは、接続された両者間の登り下りの通信量がほぼ同じ(対称)であることを前提に設計されています。最後に、DelayedACKに対する対策としては、1.受信に対して、即座に返信(送信)する。Nagleと合わせた対策をとらないと、あまり改善は期待できないかもしれません。1:49返信|引用0サインインして投票TcpAckFrequencyのレジストリを1に変更するとこの200msecの遅延はなくなるので、TCP遅延ACKが原因と推測してます。(SO_RCVBUFは正確には受信バッファサイズを指定するものですが、受信ウィンドウサイズも連動するそうです。3:55返信|引用0サインインして投票>この方法を具体的に教えていただけないでしょうか。それほど凝ったことではありません。1.連続通信開始を意味する通信ブロックは、Nagleを回避できるサイズを即座にやり取りする。これで連続通信開始時に特有のNagleとDeleydACKの影響を、ある程度回避できます。即座に似たようなブロックをクライアントにsend()するだけです。Nagleを回避できるサイズとはイーサーネット上のIPV4では概ね1460Byteと計算されます。一つのNagle回避として、2.(連続通信中は)必要がなくても100[ms]程度以内に1回以上の通信を行い、NagleやDeleydACKの開始の条件が成立しないようにする(通信間隔をあけない)。5:43返信|引用すべての返信0サインインして投票TCP遅延ACK無効化の方法についてと同件でしょうか。質問から1ヶ月経過し誰も回答していないようなので、マルチポストとは少々状況が異なるとは思いますが、提示すべきとは思います。状況を整理したく思います。ACKとは受信側が正常に受信完了した旨を送信側に通知する機能です。SOでのコメントによるとread()にて実行時間を測定されたとのことですが、read()時間とACK応答タイミングの違いがよくわかりませんでした。送信側へACKを応答しようがしなかろうが受信側の受信時間は変わらないのではありませんか?ネットワークカードにはTCPオフロード機能を有しているものもあり、OS側で明示的にACK応答パケットを生成しなくても自動的にACK応答してくれるものもある(かなぁ)と思います。今回「無線アダプタ」という新たな情報が加えられています。Acknowledgmentを備えたものもあると聞きます。回答ではなく一般論になってしまいます。TCP_NODELAYオプションはNagleを無効化するもので、DelayedACKとの相乗的な遅延に対するある程度の効果が期待できますが、それ自体を無効化するものではありません。当たり前ですがNagleアルゴリズム(RFC896)とDelayedACK(RFC1122)は別物です。次に、これらは標準的に実装されていて、回避することは一般的にはできません。OS自体もこれを前提として実装されていると予測できるため、これらを外した場合、OSの動作が不安定になる可能性を覚悟しなければなりません。従ってピアツーピア接続などの限定的な場合を除いて現実的な選択肢にはなりません。両者の悪い影響を少なくするための傾向と対策的な手法は色々とあるようです。それらを行ってみるべきではないでしょうか。前提として、これらのアルゴリズムは、接続された両者間の登り下りの通信量がほぼ同じ(対称)であることを前提に設計されています。最後に、DelayedACKに対する対策としては、1.受信に対して、即座に返信(送信)する。Nagleと合わせた対策をとらないと、あまり改善は期待できないかもしれません。佐祐理様ご返信ありがとうございます。>Oでのコメントによるとread()にて実行時間を測定されたとのことですが、read()時間とACK応答タイミングの違いがよくわかりませんでした。送信側へACKを応答しようがしなかろうが受信側の受信時間は変わらないのではありませんか?説明が不足していたので補足します。ネットワーク構成ですが、以下の3つのデバイスがあります。クライアントPCサーバーPCルータここで、クライアントPCとルータは有線、ルータとサーバーPCが無線で通信しています。ソケット通信の実行時間は以下のステップの合計時間を見ています。クライアントPCでサーバーPCのIPアドレスを指定してソケットオープンサーバーPCにデータ送信サーバーPCからデータ受信ソケットクローズここで、3のデータ受信において、ソフト上では120KBのデータをread()一回で受信してますが、プロトコルアナライザで中身を解析したところ、いくつか分割されたパケットを受信しており、パケット複数個(不特定)に対しサーバーPCにACKを返しています。プロトコルアナライザそれぞれの時間解析をしたところ、パケット受け取ってからACKを返すまでの時間はほとんどは数百usecかかっているのに対し、最初だけは約200msecと非常に遅くなってます。TcpAckFrequencyのレジストリを1に変更するとこの200msecの遅延はなくなるので、TCP遅延ACKが原因と推測してます。Acknowledgmentを備えたものもあると聞きます。この辺りはどうでしょうか?実行時間の測定は20回測定して最小、最大、平均を求めてます。確かに無線だと短期、長期で非常にばらつきが大きいです。周りの電波状態に左右され、昼間と夕方で大きく実行時間の差が出ることもあります。短時間で複数回測定してれば最小値は安定して測定できますし、いくら良い条件でも遅延ACK無効化した実行時間には絶対到達しないので無線による実験系のばらつきは別に考慮されています。SACKについては知りませんでした。3:02返信|引用0サインインして投票TcpAckFrequencyのレジストリを1に変更するとこの200msecの遅延はなくなるので、TCP遅延ACKが原因と推測してます。(SO_RCVBUFは正確には受信バッファサイズを指定するものですが、受信ウィンドウサイズも連動するそうです。3:55返信|引用0サインインして投票>>中澤様ご返信ありがとうございます。>次に、これらは標準的に実装されていて、回避することは一般的にはできません。OS自体もこれを前提として実装されていると予測できるため、これらを外した場合、OSの動作が不安定になる可能性を覚悟しなければなりません。従ってピアツーピア接続などの限定的な場合を除いて現実的な選択肢にはなりません。レジストリ変更もすごく抵抗があってなるべくやりたくなかったのですが・・>最後に、DelayedACKに対する対策としては、1.受信に対して、即座に返信(送信)する。この方法を具体的に教えていただけないでしょうか。read処理はソフトから見れば1つの関数なのですが、その処理中で複数パケットの受信に対しACKしている部分で遅延が起きているので、ソフトでどうにも手が出せないです。何か使い方で解決できるのであればそうしたいのですが。それとももっとTCPプロトコルのもっと低レベル層をプログラミングできれば解決するのでしょうか。4:02返信|引用0サインインして投票>1.~4.の「ステップの合計時間を見てい」るということは「1.~4.の合計時間」が早くしたいことでしょうか?はい。>遅延ACKが原因で後続データが送信されず、送信時間が増加してしまうのであれば、単純に考えれば、受信側の受信ウィンドウサイズを拡大すればいいように思いますが、その点については対策済みでしょうか?試してみます。どこかでACKは返さないといけないので、受信データをひとつにまとめたとしても、その後に早くACKを返せなければやはり遅くはなると思います。4:47返信|引用0サインインして投票>この方法を具体的に教えていただけないでしょうか。それほど凝ったことではありません。1.連続通信開始を意味する通信ブロックは、Nagleを回避できるサイズを即座にやり取りする。これで連続通信開始時に特有のNagleとDeleydACKの影響を、ある程度回避できます。即座に似たようなブロックをクライアントにsend()するだけです。Nagleを回避できるサイズとはイーサーネット上のIPV4では概ね1460Byteと計算されます。一つのNagle回避として、2.(連続通信中は)必要がなくても100[ms]程度以内に1回以上の通信を行い、NagleやDeleydACKの開始の条件が成立しないようにする(通信間隔をあけない)。5:43返信|引用0サインインして投票ただ、どこかでACKは返さないといけないので、受信データをひとつにまとめたとしても、その後に早くACKを返せなければやはり遅くはなると思います。SOからずっと、質問者さんの「早くしたいこと」と「遅延ACK応答」とが結び付いていないように見受けられます。ACKは何か送信するパケットがあればそのついでとして送信できます。遅延ACK応答とは無条件に送信を遅らせるものではなく、何か送信するパケットがないかを一定時間待つ機能です。5:48返信|引用0サインインして投票>1.~4.であれば3.の受信ACKは4.のクローズに付加されるだけのことではありませんか?ようやく理解できました。ACKはread処理内で閉じてるのだと思い込んでました。SO_RCVBUFの方法を試してみます。