【问题标题】:socket program is able to connect to the port which is still in TIME_WAIT套接字程序能够连接到仍在 TIME_WAIT 中的端口
【发布时间】:2010-09-28 21:36:52
【问题描述】:
  1. 我写了一个非常简单的socket服务器。
  2. 它在 63254 后监听。
  3. 首先我做了一个socket_create、socket_bind、socket_listen,所以这里有一个连接正在监听。
  4. 然后在一个循环中我做套接字accpet。所以这里再听一听。
  5. read 函数读取直到我输入退出。
  6. socket_accept 的资源 id 关闭之后。
  7. 然后主连接关闭。

当我在关闭所有连接后在 TCPview 中检查此进程时,我仍然可以看到系统进程显示 TIME_WAIT for post 63254

如果我再次运行它正在连接的套接字服务器程序,并且当一个完整进程结束时,所有连接都将关闭并且程序终止,现在我可以看到同一端口的另一个 TIME_WAIT。但我仍然可以第三次连接到同一个端口。

在stackover问题的答案中说,处于等待状态的端口无法进行连接。

我打开了 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);
?>

如果这还不够,需要改进更好的客户端服务器的建议。这段代码只是儿戏。只是想了解沟通的运作方式。

【问题讨论】:

    标签: php-socket


    【解决方案1】:

    在stackover问题答案中是 表示无法连接 对于处于等待状态的端口。

    我不知道您指的是什么答案,但您不能绑定 到处于 TIME_WAIT 状态的端口。如果你是服务器,你可以使用 setReuseAddress() 来克服这个问题。如果您是客户端,则必须等待,或者使用不同的出站端口,或者最好根本不指定出站端口,让系统找到一个。你是服务器,所以这不适用于你。

    我打开firefox浏览器它打开了4 连接。当我把它全部关闭时 关闭,系统进程显示4 时间等待 2 分钟。整天 等待停留 2 分钟,然后 消失。

    但那些是客户端端口。出站端口。在您的服务器上,它们是入站端口,并且在同一端口号上还有一个侦听端口。只要有监听端口,入站连接就可以成功。

    所以我的结论是每个 连接关闭等待的时间是 发生并且无法避免。

    TIME_WAIT 发生在您是发送最先关闭的结束时。如果您是收到关闭并作为响应关闭的结束,那么您的端口根本不会进入 TIME_WAIT。

    【讨论】:

    • 哦。我得到了很多信息。我需要处理你的回答。需要一些时间。除了。上面的代码正确退出,我可以看到一次等待 2 分钟。这正常吗。第一个代码是服务器,第二个是客户端。我不知道我钓到了一条大鱼。
    • 我告诉过你什么是正常的。我不知道鱼和它有什么关系。
    • 啊。大鱼意味着我有很多工作要做,我从你那里得到了很多信息。大鱼 = 超出预期的信息。
    • 所以,根据你的最后一段,我需要我的代码不要进入等待时间。你能建议我的代码中缺少什么吗?我仍然可以在 TCPView 中看到很多时间等待。这是否意味着像 firefox 这样的程序会让等待时间发生?
    • 因为信息对我来说是新的分析信息,所以我在 codeproject (codeproject.com/Messages/3621673/…) 中发布了相同的问题并得到了明确的答复。我正在分析这个答案并检查文档,同时我发现 EJP 所说的是正确的,但我仍然需要理解他的回复中的许多概念。与此同时,我正在等待其他人提出他们的建议。只是期望如堆栈溢出提示所述获得答案。 hasta luego。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-16
    • 1970-01-01
    相关资源
    最近更新 更多