4

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

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

我有一个显示嵌套查询的函数,我发现当我运行它并检查直到端口从 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
4

3 回答 3

0

我读到 TIME_WAIT 应该完全阻止我绑定,但这似乎不是真的。

您可以使用一个选项来绑定 TIME_WAIT 中的本地端口。这对于确保您在杀死服务器后不必等待 4 分钟再重新启动它非常有用。

int flag = 1;
sockfd = socket(...);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
bind(...);
于 2011-04-20T12:44:43.593 回答
0

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

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

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

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

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

于 2011-04-08T13:00:05.310 回答
-2

Before closing a socket, you must read all the data sent by its peer, otherwise it will stay in TIME_WAIT to ensure a new socket will not read data intended for the previous (closed one). You could also try the no lingering option of the socket.

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

于 2012-02-02T08:58:47.490 回答