4

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));
4

2 に答える 2

4

ダンプから欠落している追加のパケット、サーバー バイト 2383 ~ 2385 があるように見えることに注意してください。

サーバーが間違った ACK で応答していません。ストリームで見た最後のバイト番号 #119 の ACK で応答しています。一定期間後にサーバーが ACK に失敗した場合、欠落しているバイトを再送信するのはクライアント次第です。代わりに、RST を送信しています。

タイミング情報はありませんが、情報が再送信される前に、RST がクライアントのタイムアウトから来ていると推測する必要があります。

于 2012-10-12T16:01:30.480 に答える
2

TCPはそれ自体「不安定」ではなく、プロトコルです。何かが不安定な場合、それはネットワーク接続です。TCP には、不安定なネットワークで再試行するためのアルゴリズムがあります。コードに何か問題がある可能性もあり、仲介デバイスが接続をタイムアウトさせている可能性もあります。

于 2012-10-12T13:08:00.683 に答える