1
Socket SocketSrv;
public static ManualResetEvent Done = new ManualResetEvent(false);
IPEndPoint IPP = new IPEndPoint(IPAddress.Any, 1234);

void Listening()
{
    SocketSrv = new Socket(AddressFamily.InterNetwork,
                           SocketType.Stream, ProtocolType.Tcp);
    try
    {
        SocketSrv.Bind(IPP);
        SocketSrv.Listen(5);

        while (true)
        {
            Done.Reset();
            info.Text = "Waiting for connections....";
            SocketSrv.BeginAccept(new AsyncCallback(Connection),
                                  SocketSrv);
            Done.WaitOne();
        }
    }
    catch(Exception error)
    {
        MessageBox.Show(error.Message);
    }
}

void Connection(IAsyncResult ar)
{
    Done.Set();
    Socket con= (Socket)ar.AsyncState;
    Socket handler = con.EndAccept(ar); 
}

ManualResetEvent由于我从未使用过它,因此我正在尝试了解此异步操作中的内容。

  • 第1步。创建它SocketSrv是为了接受 TCP 连接,发送和接收“命令”的类型是流。

  • 第2步。套接字与 ip,port 绑定,然后我们开始监听连接。

  • 第三步。在 while 循环中:

    • ManualResetEvent是重置(我知道这是ManualResetEvent一个类型为布尔值的类,并指示线程何时忙)。在这种情况下,事件总是被重置,因为如果建立了连接并且另一个连接即将到来,我需要重置它并再次开始“操作”。

    • BeingAccept我正在启动异步操作中,执行的回调函数和IAsyncResult将成为“套接字”的参数。

  • 第4步。is now Waiting 阻塞当前ResetEvent线程并等待连接方法中的处理程序结束,以便它可以完成初始化当前连接。

  • 第五步。在连接线程中,ResetEvent将信号设置为 true,这意味着......好吧,我不知道这意味着什么。我认为它告诉ResetEvent解除阻塞主线程。

在“con”套接字中,我得到了AsyncState. 我不知道这意味着什么。

在处理程序套接字中,我告诉ResetEvent连接已建立。

说了这么多,有人能告诉我我说的是真的还是错的,为什么?

4

1 回答 1

1

使用该事件以便在调用该方法BeginAccept之前不会再次调用连接发生时。Connect例如WaitOne暂停线程直到Set被调用。 Reset被调用以将事件的状态设置回已发出信号,以便WaitOne再次停止线程,以便它等待Connect再次被调用。

就个人而言,我不使用这种特定的模式。我从未见过对这种模式的意义的解释。BeginAccept如果循环和方法之间存在一些共享状态Connect,那可能是有意义的。但是,正如所写,没有任何状态是通过使用事件来保护的。当我使用时,BeginAccept我根本不使用事件,并且我使用这样的代码每秒处理许多连接。使用该事件无法防止一次连接过多的错误。坦率地说,使用异步方法并强制它有效地同步会破坏目的。

从的AysncState角度来看BeginAccept, 只是不透明的数据。它是用于特定异步操作的“状态”。这种“状态”是特定于应用程序的。当您想要异步处理连接时,您可以使用任何您需要的东西。在BeginAccept回调的情况下,您通常希望对服务器套接字做一些事情,并且它被传入状态,因此您可以访问它来调用EndAccept. 由于SocketSrv是成员字段,因此您实际上不需要这样做,您可以这样做:

SocketSrv.BeginAccept(new AsyncCallback(Connection), null);
//...
void Connection(IAsyncResult ar)
{
    Socket handler = SocketSrv.EndAccept(ar); 
    //...
}

您的评论似乎表明您对这段特定的代码有很好的掌握。您的“Step4”有点偏离,它不是等待Connection方法结束,只是等待它开始(因为Set被称为第一行)。是的,“Step5”,这Set意味着它解除WaitOne了主线程调用调用Resetthen的阻塞BeginAccept

于 2013-03-31T16:52:38.540 回答