スポンサーリンク

このドキュメントの内容は、以下の通りです。

はじめに

インターネットが広く利用されています。インターネットは、ネットワーク機器やサーバと呼ばれるようなコンピューター同士が通信をしてなりたっています。それらの機器たちは、ある決められたルールに則って、通信をしています。インターネットを支える技術の1つが TCP/IP と呼ばれるプロトコルです。TCP/IP の IP は、インターネットプロトコルの略です。通信には状態があり、通信がはじまり、通信が終わるまで、状態は刻々と変化していきます。

TCP には状態がある

TCP には、状態があります。例えば、以下の状態があります。

  • クローズしている状態
  • 接続を待っている状態
  • 接続が確立をした状態
  • 接続を依頼している状態
この例は、すべての状態ではなく、ほかの状態もあります。

TCPの状態を確認する方法

TCPの状態を確認する方法として、 netstat コマンドが用意されています。 Linux や FreeBSD 、Mac, Windows に netstat コマンドがあります。

Unix系OSやMacならターミナルを起動して、 netstat コマンドを実行します。 Windows であれば、PowerShellやコマンドプロンプトを起動して、 netstat コマンドを実行します。 WindowsのWSL1(Windows Subsystem for Linux)だと netstat で状態が取れないようです。

netstatコマンドのTCPのステータスの意味


netstatコマンドのTCPのステータスの意味について紹介いたします。

LISTEN


一言で言うと、コネクションをlisten (リッスン)しています。
もう少し、かみ砕いて言うと、接続待ちしている状態です。

TCPには、パッシブオープンとアクティブオープンと呼ばれるものがあります。
パッシブオープンというのは、接続を待つ状態のことです。接続(コネクション)を待つために listen 状態になります。

サーバとクライアントがいて、サーバは接続を待っていて、クライアントは、サーバに接続にいきます。
皆さんが、ググるとき(ウェブで検索をするとき)に、利用している グーグルのサーバは、常に接続を待っている状態です。

SYN_SENT


サーバに接続要求(SYNchronize)を送信し、応答(ACKnowledgement)を受けていない状態です。ACKを受け取るとESTABLIHSEDへ移行します。
SYN は、日本においては、シンと発音されます。 SYN パケット(シンパケット)とも呼ばれています。
SYN とACK のやり取りは、スリーハンドウェイシェイクと呼ばれています。

TCPには、パッシブオープンとアクティブオープンと呼ばれるものがあります。
アクティブオープンの場合に、まず、SYN_SENT の状態になります。

皆さんが、ググるとき(ウェブで検索をするとき)に、利用している グーグルのサーバは、常に接続を待っている状態です。皆さんがスマホやパソコンでググルときに、ブラウザを利用しますが、ブラウザがグーグルに検索クエリを投げるときに、まず、TCPの接続を開始します。グーグルのサーバに接続の要求を送ります。それが、SYN_SENT です。

SYN_RCVD(SYN_RECEIVED)


クライアントからSYN要求を受け取った直後の状態を指します。

サーバがlisten状態(リッスン状態)で接続を待っていて、クライアントから接続要求を受けた状態です。
グーグルのサーバが、ググってくれる人(検索してくれる人)を待っていて、ググル人がブラウザを立ち上げて、検索クエリを投げたときに、ブラウザがグーグルのサーバに接続要求を出し、その接続要求がグーグルのサーバに届いた状態のことを意味します。この状態では、まだ、ブラウザから検索クエリは、送信されていません。

ESTABLISHED


ESTABLISHEDは、エスタブリッシュッドと読みます。
TCPにおいて、通信確立の状態です。TCPでの接続が確立されており、現在通信が行われている状態です。

サーバがクライアントの接続要求を了承し、クライアントとサーバで、お互いに通信ができるようになった状態です。

FIN_WAIT_1


通信の終了(クローズ)も2つのクローズがあり、アクティブクローズとパッシブクローズにわかれます。
通信のクローズは、通信をやめたいほうがやめればいいので、TCPにおいては、サーバからやめる、クライアントからやめる、という決まりはないと思います。

FIN_WAIT_1 は、アクティブクローズです。通信がやめたい方が、もう片方の相手に、 FIN を送信します。

FIN_WAIT_1 は、 どちらかからFINが送信された状態で、もう片方からの応答としてACKを受信するとFIN_WAIT_2へ移行し、その前にFINを受信するとCLOSINGに移行します。

FIN_WAIT_2


ACK受信状態です。次は、TIME_WAITへ移行します。

TIME_WAIT


接続終了待ちの状態です。
TIME WAITの状態は、最大パケット生存時間 MSL(Maximum Segment Lifetime)の2倍の時間、続きます。OSなどの実装によりますが、30-120秒程度で終了します。そのため、TIME_WAITのステータスの状態のコネクションがたまるケースがあります。

サーバまたはクライアントのいずれかが、TCPの接続終了要求の確認を確実に受信するために、十分な時間を待ちます。

通信が終わったのだから、もう、何かを待つ必要はないのではないか?と思われる方もいらっしゃるかもしれません。何らかの理由で、パケットが到達していない状態で、IPとポート番号が使いまわされ、たまたまシーケンス番号もかぶって通信をはじめたときに、遅延してパケットが到達するとまずい、というのが理由のようです。
しかしながら、そのような問題は、 TCP Time Stamp Option (TCPタイムスタンプオプション)とPAWS で回避可能です。

Linux Kernel 4.4 では、 60秒の時間が経過すると TIME_WAIT が回収されます。

CLOSING


FIN_WAIT_1でFINを受け取ってコネクションが閉じられた状態です。

  • アクティブクローズ側が、FINを送信
  • パッシブクローズ側が FIN を受信
  • パッシブクローズ側が FIN を送信
  • アクティブクローズ側が、FINを受信

CLOSE_WAIT


パッシブクローズの状態です。通信を終了するよ、と言われた側です。
どちらかから送信された FIN を受信した状態を表します。次はLAST_ACKへ移ります。

アクティブクローズ側がFINを送信し、パッシブクローズ側がFINを受信した状態です。

LAST_ACK


FINに対するACK待ちの状態です。ACKを受信するとCLOSEDへ移行して終了します。

CLOSED


未使用状態のTCPポートです。通常は、表示されません。

netstatコマンドの定義


netstatコマンドは、 /usr/include/netinet/tcp_fsm.h で定義されている tcpstates の配列からステータスを表示してします。

#define TCPS_CLOSED             0       /* closed */
#define TCPS_LISTEN             1       /* listening for connection */
#define TCPS_SYN_SENT           2       /* active, have sent syn */
#define TCPS_SYN_RECEIVED       3       /* have sent and received syn */
	/* states < TCPS_ESTABLISHED are those where connections not
	   established */
#define TCPS_ESTABLISHED        4       /* established */
#define TCPS_CLOSE_WAIT         5       /* rcvd fin, waiting for close */
	/* states > TCPS_CLOSE_WAIT are those where user has closed */
#define TCPS_FIN_WAIT_1         6       /* have closed, sent fin */
#define TCPS_CLOSING            7       /* closed xchd FIN; await FIN ACK */
#define TCPS_LAST_ACK           8       /* had fin and close; await FIN ACK */
	/* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */
#define TCPS_FIN_WAIT_2         9       /* have closed, fin is acked */
#define TCPS_TIME_WAIT          10      /* in 2*msl quiet wait after close */

#ifdef  TCPSTATES
const char *tcpstates[] = {
	"CLOSED",       "LISTEN",       "SYN_SENT",
	"SYN_RCVD",
	"ESTABLISHED",  "CLOSE_WAIT",   "FIN_WAIT_1",
	"CLOSING",
	"LAST_ACK",     "FIN_WAIT_2",
	"TIME_WAIT",
};
#endif

send: FIN
FIN_WAIT_1
recv: ACK
send: nohing
FIN_WAIT_2
recv: FIN
send: ACK
TIME_WAIT
CLOSED

send: FIN
FIN_WAIT_1
recv: FIN
send: ACK
CLOSING
recv: ACK
send: nothing
TIME_WAIT
CLOSED

send: FIN
FIN_WAIT_1
recv: FIN,ACK
send: ACK
TIME_WAIT
CLOSED

SYN_RCVD から FIN_WAIT、または
ESTABLISHED から FIN_WAIT へ移行した場合、
FIN_WAIT_1 - CLOSING - TIME_WAIT - CLOSED
FIN_WAIT_1 - FIN_WAIT_2 - TIME_WAIT - CLOSED
FIN_WAIT_1 - TIME_WAIT - CLOSED
をたどります。
ESTABLISHEDからrecv: FIN、send: ACKの場合は、
CLOSE_WAIT - LAST_ACK - CLOSED
へ移行します。

スポンサーリンク
スポンサーリンク
 
いつもシェア、ありがとうございます!


もっと情報を探しませんか?

関連記事

最近の記事

人気のページ

スポンサーリンク
 

過去ログ

2020 : 01 02 03 04 05 06 07 08 09 10 11 12
2019 : 01 02 03 04 05 06 07 08 09 10 11 12
2018 : 01 02 03 04 05 06 07 08 09 10 11 12
2017 : 01 02 03 04 05 06 07 08 09 10 11 12
2016 : 01 02 03 04 05 06 07 08 09 10 11 12
2015 : 01 02 03 04 05 06 07 08 09 10 11 12
2014 : 01 02 03 04 05 06 07 08 09 10 11 12
2013 : 01 02 03 04 05 06 07 08 09 10 11 12
2012 : 01 02 03 04 05 06 07 08 09 10 11 12
2011 : 01 02 03 04 05 06 07 08 09 10 11 12
2010 : 01 02 03 04 05 06 07 08 09 10 11 12
2009 : 01 02 03 04 05 06 07 08 09 10 11 12
2008 : 01 02 03 04 05 06 07 08 09 10 11 12
2007 : 01 02 03 04 05 06 07 08 09 10 11 12
2006 : 01 02 03 04 05 06 07 08 09 10 11 12
2005 : 01 02 03 04 05 06 07 08 09 10 11 12
2004 : 01 02 03 04 05 06 07 08 09 10 11 12
2003 : 01 02 03 04 05 06 07 08 09 10 11 12

サイト

Vim入門

C言語入門

C++入門

JavaScript/Node.js入門

Python入門

FreeBSD入門

Ubuntu入門

セキュリティ入門

パソコン自作入門

ブログ

トップ


プライバシーポリシー