我实现了一个代理服务器,在向客户端发送最终响应后,如果我直接关闭套接字(System.Net.Sockets TCPClient.Client.Close()),那么客户端会收到连接中止错误,但如果我使用System.Net.Sockets TCPClient.getStream().Close(),它会成功工作。我想了解在第一种情况下有什么不同,为什么客户端收到错误?
发布于 2018-04-14 14:38:21
我想说,关闭套接字并不像大多数人认为的那样是微不足道的操作:)首先,你应该理解应该如何正确地完成关闭。基本上,您必须考虑到close是一种消息,就像从套接字发送的任何其他消息一样。或者换句话说,close()是通信的另一端的信息,表示对等体完成了某种工作。现在需要理解的重要一点是,拥有TCP套接字后,您可以通知对等方您已完成发送或已完成侦听。在此页面上,您可以查看它在后台的工作原理(请注意,确认和FIN是IP层消息,因此即使使用普通套接字实现,您也永远不会看到它们):http://www.tcpipguide.com/free/t_TCPConnectionTermination-2.htm
所以现在是更实际的一步。请考虑您有一个客户端和一个服务器。服务器需要接收一条消息并关闭连接。请考虑客户端只是要发送一条消息,然后关闭连接。如果您还考虑到网络需要一些时间来处理您的通信,您将意识到,如果您快速处理,客户端将在服务器收到您的消息之前关闭连接。如果可以,TCPClient.Client.Close()客户机将停止侦听任何东西(这意味着还会侦听有关服务器关闭连接的信息)。所以TCP栈来了(windows会为你做这件事)--以防你以这种方式关闭套接字,TCP栈需要通知服务器站点,无论服务器发送了什么,都会被转储。这就是为什么你会有一个例外。
所以正确的方法是:
无论如何,C# TCPClient似乎隐藏了后台套接字关闭例程的逻辑,但如果您不以正确的方式调用关闭序列,您将以错误告终。
我希望这篇有点长的解释能帮助你理解它在后台是如何工作的,并最终让你明白为什么。
如果你想了解更多,这也是一个阅读更多关于TCP协议细节的好方法:http://www.tcpipguide.com/free/t_TCPIPTransmissionControlProtocolTCP.htm
发布于 2018-04-14 14:07:18
我想为了关闭连接,你需要发送一些特殊的字节序列。并且看起来它只由tcpclient库实现,而不是由socket库实现。也许应该发送像Eof这样的东西。你可以通过tcpdump这样的网络流量工具来检查它。祝好运!
https://stackoverflow.com/questions/49828437
复制相似问题