端口卡在 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
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你需要更具体一点,因为很难知道你在做什么。较短的文本和代码示例会有所帮助。
如果在客户端中,这应该不是问题。如果是服务器端,请解释原因。
这是什么意思?如果您指的是侦听端口:您永远不应该关闭侦听器套接字。如果您不想接受多个套接字,只需在客户端套接字断开连接之前不要再次调用
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.
That should not be a problem if it's in the client. If it's server-side, please explain why.
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.您可以使用一个选项来绑定处于 TIME_WAIT 状态的本地端口。这对于确保您不必在终止服务器后等待 4 分钟才能重新启动它非常有用。
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.
在关闭套接字之前,必须读取其对等方发送的所有数据,否则它将停留在 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