开始在EndAccept()之前或之后接受新连接

时间:2014-06-22 21:57:14

标签: c# .net asyncsocket

我有一个问题,关于在套接字上的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会不会更好,所以它只处理一次接受一个连接,一旦接受,但在它实际处理之前的通信之前连接。

这两种方式似乎都有效,但我想知道哪种方法是正确的,以及一种方式是否会产生微妙的负面影响而另一种方式则不然。

我在这里缺少什么?

提前致谢。

1 个答案:

答案 0 :(得分:1)

The blocking call is EndAccept, and it blocks until there is a connection to accept.

这不是一个准确的描述。

当从客户端收到连接请求时,从EndAccept的回调中调用

BeginAccept。您可以通过BeginAccept回调再次呼叫BeginAccept,以便在建立您刚刚通过EndAccept收到的(上一个)连接时立即接受另一个连接(仍在连接回调中)。

因此,根本不需要使用事件来同步何时接受新连接。只需从回调中再次拨打BeginAccept