TPC 接続の「すばらしい」点の 1 つは、データが失われないことです。データが ACK されない場合、TCP はおそらくデータを再送信します。
C++ で記述されたクラシック ゲーム サーバーがあり、クライアントは Flash AS3 で記述されています。
クライアントに、X 秒ごとに 5 秒のタイムアウトで YouTube と Twitter への接続を試行するチェッカー ツールを追加しました。問題は、クライアントのインターネット接続が数秒間切断された後 (インターネット チェッカーは 1 つか 2 つのタイムアウトを受け取りますが、その後 OK を受け取ります)、サーバーからのデータの受信を開始しますが、サーバーはクライアントからのデータの受信を停止します。
これは、TCPDUMP によって受信されるフローです。
1. server > client: Flags [P.], seq 2374:2378, ack 119, win 14600, length 4
2. client > server: Flags [.], ack 2374, win 15524, length 0
3. client > server: Flags [.], ack 2378, win 15520, length 0
. [Here the client sends data to the server, but the server never receives it...]
4. server > client: Flags [P.], seq 2378:2383, ack 119, win 14600, length 5
5. server > client: Flags [P.], seq 2386:2389, ack 119, win 14600, length 3
6. client > server: Flags [.], ack 2386, win 15512, length 0
7. client > server: Flags [.], ack 2389, win 15509, length 0
8. client > server: Flags [R.], seq 127, ack 2389, win 0, length 0
ご覧のとおり、サーバーが誤った ACK でデータを送信すると、クライアントはデータを再送信する代わりに RST パケットを送信します (サーバーに強制的に接続を閉じさせます)。クライアント ログでは、サーバーから送信されたデータを受信して処理していることがわかります (そのため、サーバーが間違った ACK を送信しても接続は閉じられません)。
TCP が誤った ACK を受信した後、データを再送信する代わりに RST パケットを送信することを決定した場合は?
Socket
クライアント ソケットは、次のように定義された AS3です。
var socket:Socket = new Socket();
そして、サーバーソケットは でノンブロッキングに設定されていますfcntl()
。次のオプションもあります。
setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *)&dummyint, sizeof(int));
setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&dummyint, sizeof(int));