我有一个问题,关于在套接字上的BeginAccept之后,我可以告诉我的监听器线程它可以再次开始接受连接。
这是我的代码:
while(!mStopWaitHandle.WaitOne(0, false)) // <-- Manual Reset event to check if the service has stopped.
{
Logging.Debug("Waiting for a connection...");
socket.BeginAccept(new AsyncCallback(AcceptConnection), socket);
mReadyToAcceptWaitHandle.WaitOne(); // <-- AutoResetEvent to block until I can continue accepting connections
}
然后在我的异步回调中:
private void AcceptConnection(IAsyncResult ar)
{
mReadyToAcceptWaitHandle.Set(); // <-- Tell the listener thread to start accepting connections again
Socket socket = (Socket)ar.AsyncState;
Socket workerSocket = socket.EndAccept(ar);
... handle connection on workerSocket ...
}
这是他们在Asynchronous Server Socket Example on msdn中的表现方式。
但是从我所看到的BeginAccept
开始,并不是一个阻止呼叫。阻塞调用是EndAccept
,它会阻塞,直到有连接接受。
所以拥有mReadyToAcceptWaitHandle.Set();
,告诉侦听器线程继续接受连接,在EndAccept()之前对我来说似乎很奇怪,因为这不会导致它继续打开AcceptConnection
处理程序线程(来自我从执行中看到的,它似乎没有做到这一点,但我不知道为什么?)所有这些只是阻止了EndAccept
?
在mReadyToAcceptWaitHandle.Set();
之后拥有EndAccept
会不会更好,所以它只处理一次接受一个连接,一旦接受,但在它实际处理之前的通信之前连接。
这两种方式似乎都有效,但我想知道哪种方法是正确的,以及一种方式是否会产生微妙的负面影响而另一种方式则不然。
我在这里缺少什么?
提前致谢。
答案 0 :(得分:1)
The blocking call is EndAccept, and it blocks until there is a connection to accept.
这不是一个准确的描述。
当从客户端收到连接请求时,从EndAccept
的回调中调用 BeginAccept
。您可以通过BeginAccept
回调再次呼叫BeginAccept
,以便在建立您刚刚通过EndAccept
收到的(上一个)连接时立即接受另一个连接(仍在连接回调中)。
因此,根本不需要使用事件来同步何时接受新连接。只需从回调中再次拨打BeginAccept
。