端口卡在 Time_Wait 中

发布于 2024-10-31 08:11:33 字数 2242 浏览 1 评论 0原文

我有一个 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

I have a TCP Tunnel in C#. I need to open and close the tunnel which is my app between a server and a client. I'm using this to close the data connection to test out another app. I have to use particular ports.

On the second, third, nth connection depending on how long I wait to reconnect, I receive a 10048 error code - "Address already in use" when binding my socket. When closing the sockets, I do perform ShutDown.Both and Close in hopes of clearing out the ports, but when I do a netstat in a command prompt I still find the ports held in TIME_WAIT. I've also set the sockets to no linger. Lastly I tried to make a loop to check the status of the port, but it ends in a somewhat endless loop. I'm thinking it's that 4 minute TIME_WAIT rule.

I have a function to display a nestat query and I find that when I run that and check until the port goes from ESTABLISHED and into TIME_WAIT that I can bind, but when I use the same data from this query to bind on a loop when the status reaches TIME_WAIT, I get a 10048. Is there a brief moment in time allowed by my button click that allows me to bind? Is there a state between TIME_WAIT and ESTABLISHED I'm hitting in the loop and not when I do it with button clicks? I read TIME_WAIT should stop me from binding altogether, but this does not appear to be true. Can anybody explain this?

I apologize to you code lovers. Not thinking this will change anything though. I just need a better understanding of port states.

    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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

提赋 2024-11-07 08:11:33

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

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

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

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

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

You need to be a bit more specific as it's hard to know what you are doing. Shorter text and a code sample would help.

I need to open and close connections and then reopen them again

That should not be a problem if it's in the client. If it's server-side, please explain why.

The config file on the server is looking for a particular port, so when I reconnect I need the same port open again

What do you mean? If you mean the listening port: You should never close the listener socket. If you do not want to accept more than one socket, simply do not call Accept again until the client socket have been disconnected.

恰似旧人归 2024-11-07 08:11:33

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

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

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

I read TIME_WAIT should stop me from binding altogether, but this does not appear to be true.

There is an option you can use that will allow you to bind a local port that is in TIME_WAIT. This is very useful to ensure you don't have to wait 4 minutes after killing a server before restarting it.

int flag = 1;
sockfd = socket(...);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
bind(...);
楠木可依 2024-11-07 08:11:33

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

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文