Программа сокета может подключиться к порту, который все еще находится в TIME_WAIT - PullRequest
0 голосов
/ 28 сентября 2010
  1. Я написал очень простой сокет-сервер.
  2. Он прослушивает сообщение 63254.
  3. Сначала я сделал socket_create, socket_bind, socket_listen, поэтому здесь прослушивается соединение.
  4. Затем в цикле я делаю розетку accpet.так что здесь другое прослушивание.
  5. функция чтения читает до ввода ввода.
  6. после этого закрывается идентификатор ресурса с помощью socket_accept.
  7. и затем закрывается основное соединение.

Когда я проверил этот процесс в TCPview после закрытия всех соединений, я все еще могу видеть, как системный процесс показывает TIME_WAIT для сообщения 63254

, если я снова запускаю программу сервера сокетов, к которой он подключается, и когда одинполный процесс завершен, все соединение закрыто, и программа завершена, и теперь я могу видеть другое TIME_WAIT для того же порта.но все же я мог подключиться к тому же порту в третий раз.

в ответе на вопрос о стеке сказано, что невозможно установить соединение для порта, который находится в состоянии ожидания.

Я открыл браузер Firefox этооткрыл 4 соединения.когда я закрыл все это закрыто, и системный процесс показал 4 времени ожидания в течение 2 минут.ожидание все время остается в течение 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);
?>

нужны предложения по улучшению лучшего клиентского сервера, если этого недостаточно.этот код просто детская игра.просто пытаюсь понять, как работает связь.

1 Ответ

0 голосов
/ 28 сентября 2010

Ответ на вопрос в стеке сказал, что соединение не может быть сделано для порта, который находится в состоянии ожидания.

Я не знаю, на какой ответ вы ссылаетесь, но вы не можете привязать к порту, который находится в состоянии TIME_WAIT. Если вы сервер, вы можете использовать setReuseAddress (), чтобы преодолеть это. Если вы клиент, вам нужно подождать или использовать другой исходящий порт, или, что лучше всего, вообще не указывать исходящий порт, дайте системе найти его. Вы сервер, поэтому к вам это не относится.

Я открыл браузер Firefox, он открыл 4 соединения. когда я все это закрыл закрыт и системный процесс показал 4 время ждет 2 минуты. все время подождите 2 минуты и исчезает.

Но это клиентские порты. Исходящие порты. На вашем сервере они были входящими портами, и там был также порт прослушивания с тем же номером порта. Пока имеется прослушивающий порт, входящее соединение может быть успешным.

так что я делаю вывод, что для каждого Соединение закрыто, время ожидания происходит и его нельзя избежать.

TIME_WAIT происходит, когда вы - конец, который отправляет закрытие первым. Если вы - конец, который получил закрытие и закрыл в ответ, ваш порт вообще не перейдет в TIME_WAIT.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...