• ベストアンサー
  • すぐに回答を!

TIME_WAIT 時の振る舞い

現在、詳解 TCP/IP Vol.1 の第 18 章を読んでいます. P.275 の 2MSL 待ち状態の説明なのですが, 「MSL 値を実装する場合のルールは,TCP がアクティブクローズを実行し,最後の ACK を送ったとき,コネクションは MSL が2回繰り替えされる時間だけ TIME_WAIT に止まっていなければいけないというものだ.これにより,最後の ACK が消失した場合(この場合,他方のエンドはタイムアウトし,最後の FIN を再転送する)でも,TCP は再度 ACK を送ることが可能になる」 「コネクションが 2MSL 待ちにあるときに遅れて到着したセグメントは、いかなるものでも破棄される」 と書いてあります. 前者にある,再転送された FIN も破棄されるのですか? 破棄されるのに,それに対する ACK を送ることは可能なのですか?可能と書いてあるだけで,実際には,再転送された FIN に対する ACK は送られないということでしょうか? そこがいまいち理解できません.いくつか調べたのですが,そこのところを詳しく書いてあるものは見当たりませんでした‥.

共感・応援の気持ちを伝えよう!

  • 回答数1
  • 閲覧数2087
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • 回答No.1

> 再転送された FIN も破棄されるのですか? 「破棄」という言葉が曖昧ですが、再転送されてきた FIN は無視はされず、ACK を返します。TIME_WAIT 状態はそのための状態です。 > 破棄されるのに,それに対する ACK を送ることは可能なのですか? 「破棄」とは、単にTCP/IPスタックがパケットを無視するという意味ではありません。そして、ここでいう「セグメント」とは「アプリケーションデータ」と言い換えたほうがいいかもしれません。 ("segment" という単語は、アプリケーションが送ろうとしたデータがパケットへ分割された後の「破片」を暗に意味しています) この部分の言葉を補うとするなら、こんな感じです:  「コネクションが 2MSL待ちにあるときに遅れて到着したデータは、   いかなるものでもアプリケーションに渡されず、破棄される」 このような動作とすべき理由は明らかです。 コネクションが 2MSL待ち (TIME_WAIT状態) になったということは、相手方がこちらに送信したいデータについて、すべて受け取ったということを意味します[1]。この状態で、相手から何らかのTCPセグメント(アプリケーションデータ) を受け取るということは、それはネットワーク側で複製されてしまったパケットか、何らかの理由で相手が無駄に再送してきたパケットのいずれかのはずです。そのようなパケットに乗っているデータをアプリケーションに渡すと TCP の役目を果たせません [2] ので、破棄することになります。 > 再転送された FIN に対する ACK は送られないということでしょうか? いいえ、TIME_WAIT 状態で再度 FIN を受信したら、必ず ACK しなければなりません(そして再度 2MSL待たなければなりません)。 そうしないと、通信する双方において、送信したいデータがすべて相手方に受信されたことが保証することができなくなってしまいます。 [1] RFC 793, 3.1. Header Format  "FIN" はもう送るデータは無いよ、ということを意味する。 [2] 相手のアプリケーションが送ろうとしたデータが、勝手に増殖した  ことになるため。

参考URL:
http://www.ietf.org/rfc/rfc0793.txt

共感・感謝の気持ちを伝えよう!

質問者からのお礼

>"segment" という単語は、アプリケーションが送ろうとしたデータがパケットへ分割された後の「破片」を暗に意味しています なるほど!自分の中で,セグメントというものを勘違いしていたために,おかしくなってしまっていたのですね。 >「コネクションが 2MSL待ちにあるときに遅れて到着したデータは、   いかなるものでもアプリケーションに渡されず、破棄される」 >コネクションが 2MSL待ち (TIME_WAIT状態) になったということは、相手方がこちらに送信したいデータについて、すべて受け取ったということを意味します[1]。この状態で、相手から何らかのTCP セグメント(アプリケーションデータ) を受け取るということは、それはネットワーク側で複製されてしまったパケットか、何らかの理由で相手が無駄に再送してきたパケットのいずれかのはずです。そのようなパケットに乗っているデータをアプリケーションに渡すと TCP の役目を果たせません [2] ので、破棄することになります。 なるほど!FINを単に終了するためのもの程度にしか考えていませんでした.やはり気になるところはRFCを読み定義を確認しないといけませんね. 丁寧に回答していただき,ありがとうございます.

関連するQ&A

  • TCPの接続処理と終了処理について

    TCPでコネクションを確立するとき、制御フラグでSYN、SYN+ACK、ACKで3パケットをやりとしますが、終了手順のときは、FIN、ACK、FIN、ACKと4パケットをやりとりします。 これは何故でしょうか? コネクション確立時と同じく、FIN、FIN+ACK、ACKにしないのは何故でしょうか?教えてください。

  • RFC793 TCPのコネクション解放について

    TCPのコネクションを解放するときの手続きについて、 フラグの意味がわからない部分があります。 A────────B  →FIN,ACK→→→   (1)  ←←←←←ACK←   (2)  ←←←FIN,ACK←   (3)  →ACK→→→→→   (4) 上記の手続きにより、コネクションの解放が完了しますが、 (2)は(1)に対しての肯定応答だとわかるのですが、 (3)のACKの意味がわかりません。 何に対して応答しているのでしょうか? Bは2連続でACKを送っている理由、決まりがわかりません。 RFCには「FINとセットでACKを送らなければならない」とは書いていませんので、 決められたものではないと解釈しております。 では、なぜFINとセットでACKを送るかがわかりません。 (1)のACKについては、今までのやり取りに対するACKと解釈しており、 問題視しておりませんが、ここの解釈が間違っていたら訂正お願いします。

  • FIN,ACKとACKについて

    はじめまして。5月よりTCPソケット通信を勉強しているものです。 クライアントとサーバーのプログラムを作り試行錯誤しながら動かしているのですが一つ不思議な現象が起きたので質問させて頂きます。 処理が終わり、通信を切断する時なのですが、ソケット通信に関連する書籍やWebページを見ていると接続を切断するときにFIN,ACKを送信して相手側がACKを送信し、FIN,ACKを送信して最後にACKを送信するとなっています。図にすると以下のような感じでしょうか。 PCA       PCB FIN,ACK送信 → FIN,ACK受信 ACK受信   → ACK送信 FIN,ACK受信 → FIN,ACK送信 ACK送信   → ACK受信 この手順でPCA,PCBともに切断されるとあるのですが、自分が作ったプログラムを実行させて、etherealでパケットをモニタリングすると以下のような状態で終わってしまいます。 PCA       PCB FIN,ACK送信 → FIN,ACK受信 FIN,ACK受信 → FIN,ACK送信 ACK送信   → ACK受信 PCAからのFIN,ACK受信に対してのACKの送信が省略されて、いきなりFIN,ACKを送信してしまいます。その後PCAからはACKが返されて終了となります。 プログラム的には希望通り動作しているので問題は無いのですが、なぜ途中のACKが省略されてしまうのか原因が知りたいです。また、自分の認識が間違っている場合のご指摘等頂ければと思います。 つたない文章で申し訳ありませんがご存知の方がいらっしゃいましたら教えて下さい。

  • UDPデータ通信中の認識方法

    はじめまして。 表題の件について教えて下さい。 機器Aと機器BでUDPデータの通信をしている場合(機器Bのファイルを機器Aに転送しているとか)に受信側の機器Aはデータを受信している最中であるとどうやって認識しているのでしょうか? TCPだと最初にコネクションを確立して最後にコネクションを切断するのでデータ受信開始、受信中、受信完了はコネクション情報で確認できると思うのですが、UDPではコネクション確立がないのでTCPでのデータ受信開始、受信中、受信完了をどうやって識別しようか迷っています。 UDPでデータを受信している最中にLANケーブルを抜かれたらエラーとしたいのです。 その為に受信中であることを知りたいのですが。。。。

  • wait中にinterruptを呼ばれたスレッドの振る舞いについて

    はじめまして。javaの初心者です。 どうしてもわからないことがあります。 例えば、以下のコードで、 class Foo { public synchronized void foo() { while(条件) { try { this.wait(); } catch(InterruptedException ex)    {     処理    } } } } wait中であったスレッドは、他のスレッドによって interrupt()メソッドを実行されたときは、Fooの ロックを取得してからcatch節を実行すると思うのですが、もし、以下のコードの場合は、 class Foo { public synchronized void foo() throws InterruptedException { while(条件) { this.wait(); } } } wait中であったスレッドは、他のスレッドによって interrupt()を実行されたときにすぐにInterrupted Exceptionをスローするのか、それとも Fooクラスのロックを取得してからInterruptedExceptionをスローするのかどちらなのか がわかりません。どうか教えてください。よろしく お願いします。

    • ベストアンサー
    • Java
  • これは自宅サーバーがのっとられているのでしょうか・・・

    私は、自宅サーバー(OS:CentOS5)を市販のルーター経由で公開しております。 市販のルーターのパケットフィルタリング機能にてローカルのサーバーIPへ転送している状態です。 転送許可しておりますのは、 53(TCP,UDP) 80(TCP) 110(TCP) 25(TCP)のみの状態です。 また、/etc/http/conf/vhosts/以下のバーチャルドメインの設定先はpublic_html/.htaccessでローカルからしか参照出来ない設定です 下記のコマンド実行時、なぜかESTABLISHED状態がある状態です。 # netstat -an|grep tcp tcp 0 0 0.0.0.0:587 0.0.0.0:*LISTEN tcp 0 0 192.168.122.1:530.0.0.0:*LISTEN tcp 0 0 0.0.0.0:21 0.0.0.0:*LISTEN tcp 0 0 0.0.0.0:25 0.0.0.0:*LISTEN tcp 0 1 192.168.11.99:58849 219.153.***.***:80 LAST_ACK tcp 0 0 192.168.11.99:33220 83.217.***.***:80 ESTABLISHED tcp 0 0 192.168.11.99:33225 83.同じIP.212:80 ESTABLISHED tcp 0 0 192.168.11.99:33187 83.同じIP.212:80 FIN_WAIT2 tcp 0 0 192.168.11.99:33194 83.同じIP.212:80 FIN_WAIT2 tcp 1 0 192.168.11.99:50745 41.同じIP.43:80CLOSE_WAIT tcp 0 0 192.168.11.99:50746 41.同じIP.43:80ESTABLISHED tcp 0 0 192.168.11.99:44627 72.***.***.145:80ESTABLISHED tcp 0 0 :::993 :::* LISTEN tcp 0 0 :::995 :::* LISTEN tcp 0 0 :::110 :::* LISTEN tcp 0 0 :::143 :::* LISTEN tcp 0 0 :::80 :::* LISTEN tcp 0 0 :::22 :::* LISTEN tcp 0 0 :::443 :::* LISTEN tcp 0 0 ::ffff:192.168.11.99:80::ffff:209.同じIP.34:41903 ESTABLISHED tcp 052 ::ffff:192.168.11.99:22::ffff:192.168.11.30:1334 ESTABLISHED tcp 0 0 ::ffff:192.168.11.99:80::ffff:209.同じIP.34:41094 TIME_WAIT tcp 0 0 ::ffff:192.168.11.99:80::ffff:209.同じIP.34:41088 TIME_WAIT tcp 0 0 ::ffff:192.168.11.99:80::ffff:70.同じIP.130:49439 TIME_WAIT tcp 1 0 ::ffff:192.168.11.99:80::ffff:70.同じIP.130:48291 CLOSE_WAIT 自分でXenによる仮想OSは構築しておりません。 そして自分のグローバルIPでアクセスした際のdefaultユーザー(www)のアクセスログ(/var/log/httpd/access_log or error_log)を 見ておりましても、全然アクセスされている形跡がなく自分のローカルIPしか載っていない状態でございます。 #ifconfig eth0 Link encap:Ethernet HWaddr 00:0A:79:28:BA:09 inet addr:192.168.11.99 Bcast:192.168.1.255 Mask:255.255.255.0 inet6 addr: fe80::20a:79ff:fe28:ba09/64 Scope:Link eth1 Link encap:Ethernet HWaddr 00:90:99:7D:8B:42 UP BROADCAST MULTICAST MTU:1500 Metric:1 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 virbr0 Link encap:Ethernet HWaddr 00:00:00:00:00:00 inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0 inet6 addr: fe80::200:ff:fe00:0/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:6 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 b) TX bytes:468 (468.0 b) 下記を参照した際や # netstat -an|grep tcp # tcpdump -i eth0 -l -x -s 1500 -v ! port 22 としてみた場合、あきらかにパケットが流れているのを確認できます。 # tcpdump -i eth1とvirbr0 -l -x -s 1500 -v ! port 22 としてみた場合は、特にパケットが流れている様子は確認できません。 上記のvirbr0は自分で作った覚えがないのですが、OSインストール時にデフォルトで存在していたかは、お恥ずかしながら覚えておりません。 また192.168.122.1:53のIPとポート53番を設定した覚えもございません。 ethカードは2枚挿さっておりますが、特にeth1を設定した覚えもございません。 # ll /etc/sysconfig/network-scripts/*virbr0*は確認できません。 お忙しい所恐縮ですが、これはどうゆう状態であるのか・・・を、先輩方のご経験とご判断をお伺い出来ましたらと思っております。 よろしくお願い致します。

  • waitのつもりがwaitされない!

    c言語初心者です。 ライントレーサーを作っています。 とりあえず前進して後進してを繰り返しそうと思って、以下のプログラムを立てました。 #include <pic.h> __CONFIG(HS&WDTDIS&PWRTEN&UNPROTECT); int wait(long); void main(void) { int motor; TRISB=0x00; while(1) { motor=0x90; wait(1000); motor=0x60; wait(1000); PORTB=motor; } } int wait(long a) { long i; for (i = 0; i < a; i++); return 0; } motor=0x90が前進で motor=0x60が後進です。 これで動かしたところ、後進しかしませんでした。 どこに原因があるのでしょうか。 ご教授おねがいします。

  • TIME_WAIT となったセッションを早く終了させる方法はありませんか?

    webベースのロールプレイングゲームを管理している者です。 昔から、夕方から深夜にかけてなどつながりにくい状況になっておりますが、いままでデータベースの負荷とかいろんな問題を解決して現在にいたっております。最近のつながりにくい原因を調査したところ、接続数がものすごく増えてしまっているのが原因らしいとわかりました。しかし、netstat で見てみると、実際に接続している時間はすぐ終わり、そのあとの TIME_WAIT の状態が長いようなのです。この状態では接続はすでに終わっているはずですが、これを早く終わらせるにはどうしたらいいのでしょうか?

  • 【ソケット通信】TIME_WAITを0にする方法

    【現状】 VC#でソケット通信のソフトを作成しています。 【問題】 クライアント―サーバ型のソケット通信をしようとしているのですが、切断後すぐに再接続できないという問題が生じております。 【調査結果】 調べたところ、TCP/IPの状態遷移でアクティブクローズ側がTIME_WAIT状態になることが分かっています。TIME_WAITの設定値には意味合いがあり、漂流中の重複パケットの問題を回避するためや最後のACK再送のためであることは理解しております。 【やりたいこと】 今回は基本的に1:1通信でルータを挟まずにやりとりするネットワークなので、TIME_WAITを0、もしくは数msecにしたいと考えています。 ※ 同じIPアドレス、ポート番号で接続したい為(ポート固定での再接続) 【自分で出した解決案の一つ】 どうもサーバ(Listenする側)からアクティブクローズすると、TIME_WAITは生じるもののクライアントから接続要求を出すと同じポートからでももう一度接続できてしまうというのは判明したので、必ずサーバから切断要求を出す仕様にすればTIME_WAITが0になるように思われます。 ただし、なぜ再接続できるのかは不明のため、すっきりしない(&環境や設定が異なると再接続できない可能性あり) 【質問】 (1) クライアント側からアクティブクローズする場合に、TIME_WAIT状態を1秒未満に設定する方法はありますか?(VC#で) (2) サーバからアクティブクローズした場合に、なぜ再接続できてしまうのでしょうか? 以上の2点の質問に、どうかご回答のほどよろしくお願いいたします。

  • Time and tide wait ・・の訳

    Time and tide wait for no man. の翻訳は「時間と状況は人を待たない」と言うのが一般的に正解となってます。 私には、「時間と状況は人以外(no man)を待つ」としか訳せません。 結局、人を待ってくれないので「時間と状況は人を待たない」と言うことに なるのでしょう。 でも、私の中ではどうしてもno が動詞にかかって、否定する「待たない」とはなりません。 私の理解はどこが間違ってるのでしょうか?