C# TcpClinet LingerOption with Close() 不跳过 TIME_WAIT
C# TcpClinet LingerOption with Close() not skips TIME_WAIT
我尝试使用 C# TcpClient 连接服务器已有很多时间。例如,我连接到服务器 5 秒,断开连接,然后在 10 秒后尝试连接到服务器,然后重复...
但是尽管如此,我将 LingerOption 和 ResueAddress 选项设置为 true,当我重新连接到服务器时,ExtendedSocketExcption 出现了。
这是我的代码。 (.Net5, Windows 10)
TCPSocket = new TcpClient(new IPEndPoint("10.10.0.100", 50010));
TCPSocket.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
LingerOption lo = new LingerOption(true, 0);
TCPSocket.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lo);
TCPSocket.Connect(new IPEndPoint("10.10.0.50", 50010));
TCPSocket.ReceiveTimeout = 5000;
//Do somthing
TCPSocket.Client.Shutdown(SocketShutdown.Both);
TCPSocket.Close();
Thread.Sleep(5000);
TCPSocket.Connect(new IPEndPoint(SRE3021IP, SRE3021TCPPort)); //ExtendedSocketExeption
我在线程休眠时使用命令 netstat -ano | findstr 50010
检查 cmd。
TCP 10.10.0.100:50010 10.10.0.50:50010 TIME_WAIT 0
TIME_WAIT状态保持了大约30~1分钟然后就消失了...
我不知道为什么没有应用 linger 选项。
设置 LingerOption 不会阻止套接字关闭。它延迟 close() 以允许发送缓冲区中任何未发送的数据。这允许应用程序在网络速度较慢的情况下进入下一阶段。套接字仍会关闭。
ReuseAddress 与重用现有套接字无关(信不信由你),它允许侦听套接字绑定到现有侦听端口。这是一种非常定制的行为,需要其他进程互操作让两个不同的应用程序侦听同一端口。此选项对出站套接字连接没有用处。
您的问题源于您正在使用此行设置源绑定:
TCPSocket = new TcpClient(new IPEndPoint("10.10.0.100", 50010 ));
如果您想设置源端口,您别无选择,只能等待 OS 从连接列表中清除套接字,这意味着等待 TIME_WAIT 过期。
如果您不想设置源端口(现在很少有理由设置源端口)但仍想 select 特定的源 IP 地址接口,那么您可以使用:
TCPSocket = new TcpClient(new IPEndPoint("10.10.0.100", 0));
如果您希望 Windows 只选择最合适的传出接口(和端口),则使用:
TCPSocket = new TcpClient();
我尝试使用 C# TcpClient 连接服务器已有很多时间。例如,我连接到服务器 5 秒,断开连接,然后在 10 秒后尝试连接到服务器,然后重复...
但是尽管如此,我将 LingerOption 和 ResueAddress 选项设置为 true,当我重新连接到服务器时,ExtendedSocketExcption 出现了。
这是我的代码。 (.Net5, Windows 10)
TCPSocket = new TcpClient(new IPEndPoint("10.10.0.100", 50010));
TCPSocket.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
LingerOption lo = new LingerOption(true, 0);
TCPSocket.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lo);
TCPSocket.Connect(new IPEndPoint("10.10.0.50", 50010));
TCPSocket.ReceiveTimeout = 5000;
//Do somthing
TCPSocket.Client.Shutdown(SocketShutdown.Both);
TCPSocket.Close();
Thread.Sleep(5000);
TCPSocket.Connect(new IPEndPoint(SRE3021IP, SRE3021TCPPort)); //ExtendedSocketExeption
我在线程休眠时使用命令 netstat -ano | findstr 50010
检查 cmd。
TCP 10.10.0.100:50010 10.10.0.50:50010 TIME_WAIT 0
TIME_WAIT状态保持了大约30~1分钟然后就消失了...
我不知道为什么没有应用 linger 选项。
设置 LingerOption 不会阻止套接字关闭。它延迟 close() 以允许发送缓冲区中任何未发送的数据。这允许应用程序在网络速度较慢的情况下进入下一阶段。套接字仍会关闭。
ReuseAddress 与重用现有套接字无关(信不信由你),它允许侦听套接字绑定到现有侦听端口。这是一种非常定制的行为,需要其他进程互操作让两个不同的应用程序侦听同一端口。此选项对出站套接字连接没有用处。
您的问题源于您正在使用此行设置源绑定:
TCPSocket = new TcpClient(new IPEndPoint("10.10.0.100", 50010 ));
如果您想设置源端口,您别无选择,只能等待 OS 从连接列表中清除套接字,这意味着等待 TIME_WAIT 过期。
如果您不想设置源端口(现在很少有理由设置源端口)但仍想 select 特定的源 IP 地址接口,那么您可以使用:
TCPSocket = new TcpClient(new IPEndPoint("10.10.0.100", 0));
如果您希望 Windows 只选择最合适的传出接口(和端口),则使用:
TCPSocket = new TcpClient();