ソケット プログラムは、TIME_WAIT 状態にあるポートに接続できます。
-
26-09-2019 - |
質問
- 非常に単純なソケットサーバーを作成しました。
- 投稿 63254 でリッスンします。
- まず、socket_create、socket_bind、socket_listenを実行したので、ここでは接続がリッスンしています。
- 次に、ループ内でソケット accpet を実行します。それで、ここでもう一度聞いてください。
- 読み取り関数は、exit を入力するまで読み取ります。
- その後、socket_accept によるリソース ID が閉じられます。
- その後、メイン接続が閉じます。
すべての接続を閉じた後、TCPview でこのプロセスを確認すると、ポスト 63254 の TIME_WAIT を示すシステム プロセスがまだ表示されます。
ソケットサーバープログラムを再度実行すると、接続されており、1つの完全なプロセスが終了すると、すべての接続が閉じられ、プログラムが終了し、同じポートに対して別のTIME_WAITが表示されるようになりました。しかし、それでも3回目は同じポートに接続できました。
スタックオーバーの質問の回答では、待機状態にあるポートには接続できないと言われています。
Firefox ブラウザを開くと 4 つの接続が開かれました。閉じるとすべてが閉じ、システムプロセスは4回2分間待機することを示しました。all time wait は 2 分間留まり、消えます。
したがって、私の結論は、接続が閉じるたびに待機時間が発生し、回避することはできないということです。
スタックオーバーフローフローの多くの投稿を読みましたが、まだ確信がありませんでした。
コマンドラインで次のコードを実行します。
私のサーバーコード
<?
error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush();
$str = '';
$buff = '';
$s = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if(!$s)die('Unable to create socket');
if(!socket_bind($s,'127.0.0.1',63254))
die("\nTrying to Bind: ".socket_strerror(socket_last_error()));
if(!socket_listen($s,1))
die(socket_strerror(socket_last_error()));
while(1)
{
$acc = socket_accept($s);
if(!$acc)die(socket_strerror(socket_last_error()));
// echo "\n".gettype($acc);
if(!$acc)die(socket_strerror(socket_last_error()));
while(1)
{
$str = socket_read($acc,512);
$buff.= $str;
echo $str;
// echo '::'.gettype($str);
if($str===false)die(socket_strerror(socket_last_error()));
if($str=="exit\r\n")break;
}
// if(!socket_shutdown($acc,2))echo socket_strerror(socket_last_error());
socket_close($acc);
if(preg_match('/exit/',$buff))break;
}
//echo "\nConnection closed by server\n";
//if(!socket_shutdown($s,2))echo socket_strerror(socket_last_error());
socket_close($s);
?>
クライアントコード
<?
set_time_limit(0);
$f = fsockopen('127.0.0.1',63254,$a,$b,10);
if(!$f)die('cannot connect');
echo "\nConnected: \n";
do{
$buff = fgets(STDIN);
fwrite($f,$buff);
}while($buff!="exit\r\n");
fclose($f);
?>
これでは不十分な場合は、より良いクライアント サーバーを改善するための提案が必要です。このコードは単なる子供の遊びです。コミュニケーションの仕組みを理解しようとしているだけです。
解決
stackover質問の答えにはそれがあります 接続を行うことができないと言いました ポートの待機状態である。
私はあなたが参照している答えるのか分からないが、あなたはできません。のバインドのTIME_WAIT状態になっているポートに接続します。サーバーであれば、あなたはこれを克服するためにsetReuseAddressの()を使用することができます。あなたが待つ、または別のアウトバウンドポートを使用するか、すべての最高は、すべてのアウトバウンドポートを指定しないでくださいする必要がクライアントであれば、システムは1を見つけてみましょう。あなたはこのように、サーバーがあなたには適用されませんされます。
私はそれが4に開いたFirefoxブラウザを開きました 接続。私はそれを閉じたときに、すべての 閉じてシステム処理が4を示し 時間は2分間待機します。すべての時間 2分間待機滞在と 消滅します。
しかし、それらは、クライアントポートです。アウトバウンドポート。サーバーでは、彼らは、受信ポートだった、と同じポート番号でリスニングポートもありました。限りリスニングポートがあるとして、インバウンドconnnectionは成功することができます。
あなたがが最初にの近くに送信することを終了しているとき、私は結論するものすべてのためのものです 接続がクローズ時間待ちです 発生し、回避することはできません。
TIME_WAITが発生します。あなたが終了している場合は、そのの受信の近くに、それに応答して閉じ、すべてのTIME_WAITに入らない、あなたのポートます。