如何从服务器优雅地关闭套接字

shy*_*man 5 .net c# sockets network-programming tcp

在服务器端,我试图优雅地关闭一个连接的套接字。我知道 Socket 上的正确事件顺序应该是:

  1. 使用 SocketShutdown.Send 选项关闭套接字

  2. 循环/等待直到套接字接收返回 0 字节

  3. 套接字关闭

我有几个问题:

  1. 如果 Socket.Receive 永远不会返回(0 字节)怎么办?我们会一直试图关闭套接字吗?

  2. 每当我在服务器上调用 Close 时,客户端总是会收到“远程主机强行关闭现有连接”的异常。我怎样才能“优雅地”通知客户这个关闭?

  3. 在服务器上,如果我使用 Async Begin/EndReceive 调用,每当我在套接字上调用 Close 时,它​​总是会在 Begin/EndReceive 线程上导致 ObjectDisposedException。有没有办法在没有发生这种异常的情况下关闭套接字?

Dav*_*rtz 2

  1. TCP 协议保证套接字最终将关闭,除非对等方拒绝允许它关闭。在这种情况下,你应该永远等待或放弃,无论什么都合适。

  2. 如果在接收返回零后关闭套接字,则不会发生这种情况。如果是,则您的代码可能做错了什么。

  3. 当异步操作正在或可能正在使用资源时,您无法释放该资源。不要调用 close,而是调用 shutdown。在 100% 完成资源之前,请勿调用关闭。