端口被困在Time_Wait

时间:2011-04-08 12:54:40

标签: c# tcp ports netstat time-wait

我在C#中有一个TCP隧道。我需要打开和关闭隧道,这是我在服务器和客户端之间的应用程序。我正在使用它关闭数据连接以测试另一个应用程序。我必须使用特定的端口。

在第二个,第三个,第n个连接上,取决于我等待重新连接的时间,我在收到套接字时收到10048错误代码 - “地址已在使用中”。当关闭套接字时,我确实执行ShutDown.Both和Close以期清除端口,但是当我在命令提示符下执行netstat时,我仍然发现在TIME_WAIT中保存的端口。我也设置插座没有逗留。最后,我尝试创建一个循环来检查端口的状态,但它以无限循环结束。我认为这是4分钟的TIME_WAIT规则。

我有一个函数来显示一个nestat查询,我发现当我运行它并检查直到端口从ESTABLISHED进入TIME_WAIT我可以绑定,但是当我使用来自此查询的相同数据绑定到当状态达到TIME_WAIT时循环,我得到一个10048.我的按钮点击是否允许我绑定一个短暂的时间点?在TIME_WAIT和ESTABLISHED之间是否有一个状态我正在循环中而不是当我按下按钮点击时?我读过TIME_WAIT会阻止我完全绑定,但这似乎不是真的。有人可以解释一下吗?

我向你们代码爱好者道歉。不认为这会改变任何事情。我只是需要更好地了解港口国家。

    public bool CheckAvailablePorts()
    {
        int temp=0;
        bool availPort= true;
        m_config = new AppConfig();
        if (!m_config.initialize())
        {
            System.Diagnostics.Debug.WriteLine("Error loading configuration file.  Exiting...");
            return false;
        }
        else
        {

//checking through all the ports that have been set to connect on

            foreach (ProxyConfig cfg in m_config.m_proxyConfigs)
            {
                availPort = true;
                temp = cfg.localEP.Port;
                DataView dv = FindEstablishedSockets();//returns netstat query
                foreach (DataRowView rowView in dv)
                {
                    DataRow row = rowView.Row;

                    if ((Convert.ToInt32(row["Local Port"].ToString()) == temp) && (row["Status"].ToString().Equals("Established")))
                    {
                        System.Diagnostics.Debug.WriteLine("Port: " + temp + " is still locked");
                        availPort = false;
                        break;
                    }
                }
            }
            return availPort;
        }
    }

//snippet out of a bigger function which checks for availability and then sleeps if false and runs again

            bool temp = false;
            while (!temp)
            {
                temp = monitor.CheckAvailablePorts();
                System.Threading.Thread.Sleep(2000);
            }
            System.Threading.Thread.Sleep(3000);
            monitor.startApplication(); //starts all the binding

3 个答案:

答案 0 :(得分:0)

你需要更具体一点,因为很难知道你在做什么。较短的文本和代码示例会有所帮助。

  

我需要打开和关闭连接,然后重新打开它们

如果它在客户端,这应该不是问题。如果是服务器端,请解释原因。

  

服务器上的配置文件正在寻找特定的端口,所以当我重新连接时,我需要再次打开相同的端口

你是什​​么意思?如果你的意思是监听端口:你永远不应该关闭监听器套接字。如果您不想接受多个套接字,只需再次调用Accept,直到客户端套接字断开连接。

答案 1 :(得分:0)

  

我读过TIME_WAIT会阻止我完全绑定,但这似乎不是真的。

您可以使用一个选项,允许您绑定TIME_WAIT中的本地端口。这对于确保您在重新启动服务器之前不必等待4分钟非常有用。

int flag = 1;
sockfd = socket(...);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
bind(...);

答案 2 :(得分:-2)

在关闭套接字之前,必须读取其对等方发送的所有数据,否则它将保留在TIME_WAIT中以确保新套接字不会读取前一个(关闭的)数据。您也可以尝试套接字的无延迟选项。

详细信息:http://msdn.microsoft.com/en-us/library/windows/desktop/ms738547%28v=vs.85%29.aspx