我有一个通过 tcpListener 进行通信的服务。问题是当用户重新启动服务时 - 抛出“地址已在使用”异常,并且服务无法启动几分钟左右。
有什么方法可以告诉系统终止旧连接以便我可以打开一个新连接?(我不能只使用随机端口,因为服务无法通知客户端是什么端口,所以我们必须依赖预定义的端口)
我有一个通过 tcpListener 进行通信的服务。问题是当用户重新启动服务时 - 抛出“地址已在使用”异常,并且服务无法启动几分钟左右。
有什么方法可以告诉系统终止旧连接以便我可以打开一个新连接?(我不能只使用随机端口,因为服务无法通知客户端是什么端口,所以我们必须依赖预定义的端口)
SO_REUSEADDR
在绑定到监听端口之前设置套接字选项。看起来相应的 .NET 代码类似于:
SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
套接字在关闭后的一段时间内不使用是有原因的。一个 Socket 由一个 4 元组、Source 和 Dest Port、Source 和 Dest IP 组成。
假设您在客户端忙于向服务器发送数据时强行关闭了一个套接字。您等待 5 秒并使用相同的端口重新打开服务器,并且相同的客户端将数据发送到相同的 4 元组,服务器将收到错误的 tcp 序列号的数据包,并且连接将被重置。
你是在踢自己的脚:)
这就是为什么连接有 2-4 分钟的 time_wait 状态(取决于发行版),直到它们可以再次使用。为了清楚起见,我说的是 SOCKET,而不仅仅是监听 tcp 端口。