【问题标题】:Start Accepting new connections before or after EndAccept()在 EndAccept() 之前或之后开始接受新连接
【发布时间】:2014-06-22 21:57:13
【问题描述】:

我有一个问题,在套接字上的 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,它会阻塞直到有连接可以接受。

所以在 EndAccept() 之前让mReadyToAcceptWaitHandle.Set(); 告诉侦听器线程继续接受连接对我来说似乎很奇怪,因为这不会导致它继续打开AcceptConnection 处理程序线程(从我的从执行上看,它似乎没有这样做,但我不知道为什么?)这一切都只是阻止EndAccept

EndAccept 之后有mReadyToAcceptWaitHandle.Set(); 不是更好吗,这样它一次只处理接受一个连接,一旦它接受,但在它实际处理连接上的通信之前。

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

我在这里错过了什么?

提前致谢。

【问题讨论】:

    标签: c# .net asyncsocket


    【解决方案1】:

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

    这不是一个准确的描述。

    EndAccept 在收到来自客户端的连接请求时从BeginAccept 的回调中调用。您可以从BeginAccept 回调中再次调用BeginAccept 以立即接受另一个连接,同时建立您刚刚通过EndAccept 收到的(上一个)连接(仍在连接回调中)。

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

    【讨论】:

    • 根据 EndAccept 文档msdn.microsoft.com/en-us/library/chfa7866(v=vs.110).aspx 的备注部分,EndAccept 实际上会阻塞,直到传入连接队列中有一个连接可以接受。无论如何,从 BeginAccept 回调中调用 BeginAccept 与在等待 WaitHandle 上的信号后从与原始 BeginAccept 相同的位置调用它没有什么不同,就像我在代码中所做的那样。事实上,我的方式更清洁,并允许我对其他状态进行更多检查,如服务停止。事实上,我的方式是他们在 MSDN 示例中的做法。
    • 你甚至没有回答我的问题。
    • 当它阻塞时,它只会暂时阻塞,因为回调只会在实际上有连接接受时才被调用。
    • 你自己在stackoverflow.com/a/15557881/2709382的cmets中说BeginAccept不会阻塞。
    • OHHH AsyncCallback 仅在有要接受的连接时执行,但 BeginAccept 不会阻塞。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-28
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多