首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关闭套接字和关闭网络流(System.Net.Sockets)之间的区别

关闭套接字和关闭网络流(System.Net.Sockets)之间的区别
EN

Stack Overflow用户
提问于 2018-04-14 13:59:50
回答 2查看 362关注 0票数 1

我实现了一个代理服务器,在向客户端发送最终响应后,如果我直接关闭套接字(System.Net.Sockets TCPClient.Client.Close()),那么客户端会收到连接中止错误,但如果我使用System.Net.Sockets TCPClient.getStream().Close(),它会成功工作。我想了解在第一种情况下有什么不同,为什么客户端收到错误?

EN

回答 2

Stack Overflow用户

发布于 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栈需要通知服务器站点,无论服务器发送了什么,都会被转储。这就是为什么你会有一个例外。

所以正确的方法是:

  1. 通知服务器客户端已完成发送任何数据(FIN)
  2. 等待,直到服务器确认他知道客户端不会发送任何数据(确认)
  3. now服务器应通知客户端将停止发送数据(FIN)
  4. 现在客户端可以说-“好的,我知道了,我不会再听”(确认)

无论如何,C# TCPClient似乎隐藏了后台套接字关闭例程的逻辑,但如果您不以正确的方式调用关闭序列,您将以错误告终。

我希望这篇有点长的解释能帮助你理解它在后台是如何工作的,并最终让你明白为什么。

如果你想了解更多,这也是一个阅读更多关于TCP协议细节的好方法:http://www.tcpipguide.com/free/t_TCPIPTransmissionControlProtocolTCP.htm

票数 1
EN

Stack Overflow用户

发布于 2018-04-14 14:07:18

我想为了关闭连接,你需要发送一些特殊的字节序列。并且看起来它只由tcpclient库实现,而不是由socket库实现。也许应该发送像Eof这样的东西。你可以通过tcpdump这样的网络流量工具来检查它。祝好运!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49828437

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档