C#:如何在Socket.BeginReceive回调之前终止套接字?

Lop*_*per 5 c# sockets connection tcp

我有一台服务器接收来自客户端的连接请求.该服务器使用异步Socket.BeginReceiveSocket.EndReceive方法.代码与此处的代码非常相似.

在我的情况下,在调用之后Socket.BeginReceive我需要一个超时,这样如果客户端挂起连接但是在一段固定的时间内根本不传输任何数据,我需要终止连接.

  • 如何在此方案中终止连接?
  • 编程定时器的最佳方法是什么?

Han*_*ant 10

只需调用套接字的Close()方法即可.之后回调方法会很快运行,ObjectDisposedException当你调用EndReceive()方法时,你会得到一个.准备抓住那个例外.

您可能不想阻止调用的线程BeginReceive,您需要一个System.Threading.TimerSystem.Timers.Timer检测超时.它的回调应该调用Close().请注意这导致的不可避免的竞争条件,如果在计时器到期之前收到响应一微秒,则计时器的回调将会运行.即使你得到了很好的回复,你也会关闭套接字.下一次通话BeginReceive()将立即失败.


Xat*_*ian 7

我知道这个帖子已经很老了,但我遇到了同样的问题,我对这里给出的答案(或其他任何地方的问题)都不满意.

取消待处理的更好解决方案Socket.BeginReceive是调用Socket.Shutdown而不是Socket.Close.这样,异步处理程序"正常"引发,并且调用Socket.EndReceive返回0 - >而不是抛出丑陋的预期异常.你应该总是有一个

if (Socket.EndReceive() > 0) {
  //Do something
} else {
  //Socket has been shut down (either by you or the other end of the connection)
  //Now it's "safe" to call Socket.Close
  Socket.Close();
}
Run Code Online (Sandbox Code Playgroud)

所以你甚至不需要调整你的异步回调来处理手动取消.