为了清楚起见,我在这里提到的所有 TCPClients 都不是我自己的类的实例,它们都是来自 Mono 的 .NET 4.0 实现的 System.Net.Sockets.TcpClient 的实例。
我有一台服务器正在监听客户端连接,就像服务器一样。每当它获得一个新客户端时,它都会创建一个新的 TCPClient 来处理新线程上的连接。我正在使用字典跟踪所有连接和线程。如果客户端断开连接,它会向服务器发送断开连接消息,关闭 TCPClient,删除字典条目,线程自然死亡。没有大惊小怪,没有混乱。服务器可以毫无问题地处理多个客户端。
但是,我正在模拟如果客户端断开连接,没有机会发送断开连接消息,然后重新连接会发生什么。我正在检测客户端是否重新连接了用户名系统(完成测试后会更安全)。如果我只是创建一个新的 TCPClient 并让旧的 TCPClient 运行,系统工作得很好,但是我有一堆无用的线程在占用空间并且什么都不做。懒鬼。
所以我尝试关闭与旧连接关联的 TCPClient。当我这样做时,新的 TCPClient 也会死掉,并且客户端程序会抛出此错误:
E/mono (12944): Unhandled Exception: System.IO.IOException: Write failure ---> System.Net.Sockets.SocketException: The socket has been shut down
服务器抛出此错误:
Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.
Cannot read from a closed TextReader.
所以用远程端点关闭旧的 TCPClient 说:192.168.1.10:50001
还使用远程端点打破新的 TCPClient 说:192.168.1.10:50002
所以这两个 TCPClient 对象具有相同的远程端点 IP 地址,但不同的远程端点端口。但是关闭一个似乎会阻止另一个工作。我希望能够关闭旧的 TCPClient 来进行清理,而无需关闭新的 TCPClient。
我怀疑这与 TCPClient 如何在低级别使用套接字有关,但对此没有任何真正的了解,我无法修复它。