为了清楚起见,我在这里提到的所有TCPClient都不是我自己的类的实例,它们都是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.
因此,使用远程 endpoints 关闭旧TCPClient: 192.168.1.10:50001
同时使用远程 endpoints 打破新的TCPClient: 192.168.1.10:50002
因此,两个TCPClient对象具有相同的远程 endpoints IP地址,但具有不同的远程 endpoints 端口 . 但关闭一个似乎阻止了另一个工作 . 我希望能够关闭旧的TCPClient来进行清理,而无需关闭新的TCPClient .
我怀疑这与TCPClient如何处理低级别的套接字有关,但没有真正理解它,我无法修复它 .
3 回答
我的套接字服务器上有类似的问题 . 我使用简单的List而不是字典来保存我当前的所有连接 . 在一个侦听新流的连续while循环中,我有一个try / catch,如果它已断开连接,它会在catch块中杀死它 .
在sever.cs上有这样的东西:
然后在客户端上使用一个简单的dispose方法:
EDIT: 此粘贴是他或她在我的代码帮助下自行找到的OPs解析 .
所以要澄清一下,情况是我有两个TCPClient对象TCPClientA和TCPClientB具有不同的远程 endpoints 端口,但是相同的IP:
返回:192.168.1.10:50001
返回:192.168.1.10:50002
TCPClientA需要清理,因为它不再有用,所以我打电话
但由于某种原因,这会关闭TCPClientB另一端的客户端的套接字 . 但是,写作
成功关闭TCPClientA而不干扰TCPClientB . 所以我已经解决了这个问题,但我不明白为什么会这样 .
这听起来像是代码中的错误 . 关闭一个入站连接不应该关闭另一个 .
看起来你找到了一个解决方案但是你知道在.net中编写客户端/服务器应用程序时有许多类似的缺陷 . 有一个开源网络库(完全支持单声道),这些问题已经解决了,networkComms.net . 基本样本是here .
免责声明:这是一个商业产品,我是创始人 .