关闭和清理 Socket 连接的正确方法是啥?
Posted
技术标签:
【中文标题】关闭和清理 Socket 连接的正确方法是啥?【英文标题】:What is the proper way of closing and cleaning up a Socket connection?关闭和清理 Socket 连接的正确方法是什么? 【发布时间】:2013-02-27 14:17:12 【问题描述】:我对 Socket 对象上的相关方法的聚宝盆感到有些困惑,这些方法应该关闭和清理套接字连接。考虑以下几点:
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect("192.168.1.22", 8333);
socket.Send(Encoding.UTF8.GetBytes("hello"));
// now for the closing fun
socket.Shutdown(SocketShutdown.Both);
socket.Disconnect(false);
socket.Close();
socket.Dispose();
另外this guy表示要真正干净地关闭连接,必须执行socket.Shutdown(SocketShudown.Send)
,然后等待对方响应。
关闭然后清理套接字连接的正确方法是什么?
【问题讨论】:
那家伙说对了一半。我认为这取决于两者之间的协议。如果您希望在一段时间内仍然能够接收,那么可以,您应该告诉对方您打算关闭并说您将停止发送但仍然可以接收。 "that guy" 大部分是正确的,因为我对我的服务器代码进行了类似的建模。但我相信只有异步(非阻塞)套接字才需要半关闭然后等待的方法。我相信在非阻塞套接字的情况下,您调用“发送”后立即关闭,如果有需要重新传输的数据包,可能会发生一些边缘情况。 我对我的套接字服务器使用了混合方法。服务器会先半关闭连接,等待 recv() 返回 0 或错误,表示客户端完成。但是,我有一个计时器,它每 45 秒定期关闭一次,以扫描并关闭自上次扫描以来一直存在的任何半开连接。 使用 TcpClient 有什么办法吗? 【参考方案1】:关闭套接字关闭连接,而Close是Dispose周围的一个包装方法,所以一般
socket.Shutdown(SocketShutdown.Both);
socket.Close();
应该够了。有些人可能会争辩说,Close 的实现可能有一天会改变(所以它不再调用 Dispose),你应该在调用 Close 之后手动调用 Dispose,但我个人怀疑这会发生:)
或者,考虑使用 using (yeh):
using (var socket = new Socket(...))
....
socket.Shutdown(SocketShutdown.Both);
socket.Close();
【讨论】:
【参考方案2】:根据MSDN,对于面向连接的套接字,如果你调用Connect
,你应该调用Close
。这也适用于BeginConnect
和ConnectAsync
。
using (var socket = new Socket(...))
socket.Connect(host);
...
socket.Shutdown(SocketShutdown.Both);
socket.Close();
【讨论】:
以上是关于关闭和清理 Socket 连接的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章