理解异步服务器套接字中的ManualResetEvent

本文关键字:ManualResetEvent 套接字 服务器 异步 | 更新日期: 2023-09-27 18:06:36

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、端口绑定,然后我们开始侦听连接。

  • 步骤3。在while循环中:

    • ManualResetEvent是Reset(我理解ManualResetEvent是一个类型是布尔型的类,每当线程忙或不忙时表示)。在这种情况下,事件总是被重置,因为如果有一个连接建立,另一个即将到来,我需要重置它并再次开始"操作"。

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

  • 第四。ResetEvent现在正在等待阻塞当前线程,并等待连接方法中的处理程序结束,以便它可以完成初始化当前连接。

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

在'con'套接字中,我得到AsyncState。我不知道这是什么意思。

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

话虽如此,谁能告诉我我说的是对还是错,为什么?

理解异步服务器套接字中的ManualResetEvent

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

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

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

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

你的评论似乎表明你已经很好地掌握了这段代码。您的"Step4"有点偏离,它没有等待Connection方法结束,只是让它开始(因为Set被称为第一行)。是的,"Step5", Set意味着它解除了WaitOne的阻塞所以主线程调用调用Reset然后BeginAccept

相关文章:
  • 没有找到相关文章