【发布时间】:2011-02-28 20:55:05
【问题描述】:
我有一个通过 tcpListener 进行通信的服务。 问题是当用户重新启动服务时 - 抛出“地址已在使用”异常,并且服务无法启动几分钟左右。
有什么方法可以告诉系统终止旧连接,以便我可以打开一个新连接? (我不能只使用随机端口,因为服务无法通知客户端是什么端口,所以我们必须依赖预定义的端口)
【问题讨论】:
标签: c# sockets tcp terminate tcplistener
我有一个通过 tcpListener 进行通信的服务。 问题是当用户重新启动服务时 - 抛出“地址已在使用”异常,并且服务无法启动几分钟左右。
有什么方法可以告诉系统终止旧连接,以便我可以打开一个新连接? (我不能只使用随机端口,因为服务无法通知客户端是什么端口,所以我们必须依赖预定义的端口)
【问题讨论】:
标签: c# sockets tcp terminate 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 端口。
【讨论】: