Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 理解异步服务器套接字中的ManualResetEvent_C#_Asyncsocket - Fatal编程技术网

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

C# 理解异步服务器套接字中的ManualResetEvent,c#,asyncsocket,C#,Asyncsocket,我试图理解这个异步操作中的ManualResetEvent,因为我从未使用过它 第一步。创建的SocketSrv用于接受TCP连接,发送和接收“命令”的类型为流 第二步。套接字与ip、端口绑定,然后我们开始侦听连接 第三步。在while循环中: ManualResetEvent被重置(我知道ManualResetEvent是一个类型为布尔型的类,它指示线程是否繁忙)。在这种情况下,事件总是被重置,因为如果建立了一个连接,并且另一个连接即将到来,我需要重置它并再次启动“操作” 在BeingAc

我试图理解这个异步操作中的
ManualResetEvent
,因为我从未使用过它

  • 第一步。创建的
    SocketSrv
    用于接受TCP连接,发送和接收“命令”的类型为流

  • 第二步。套接字与ip、端口绑定,然后我们开始侦听连接

  • 第三步。在while循环中:

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

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

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

  • 第五步。在连接线程中,
    ResetEvent
    将信号设置为true,这意味着。。。我不知道这是什么意思。我想它会告诉
    ResetEvent
    取消阻止主线程

在“con”套接字中,我得到了
异步状态
。我不知道这意味着什么

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


话虽如此,有人能告诉我我所说的是否正确以及原因吗?

使用该事件,以便在连接发生时,在调用
Connect
方法之前,不会再次调用beginacept。e、 g.
WaitOne
暂停线程,直到调用
Set
<调用code>Reset将事件的状态设置回Signaled,以便
WaitOne
将再次停止线程,以等待再次调用
Connect

就我个人而言,我不使用这种特殊模式。我从来没有见过对这种模式的意义的解释。如果
beginacept
循环和
Connect
方法之间存在某种共享状态,那么这可能是有意义的。但是,如文中所述,事件的使用不会保护任何状态。当我使用
beginacept
时,我只是不使用事件,我使用这样的代码一秒钟处理许多连接。使用事件无法防止一次连接过多的错误。坦率地说,使用异步方法并强制它有效地同步,这是行不通的

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

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); 
}

您的评论似乎表明您已经很好地掌握了这段特定的代码。您的“Step4”有点不正确,它不是等待
连接
方法结束,而是等待它开始(因为
设置
被称为第一行)。是的,“Step5”,即
Set
意味着它将取消阻止
WaitOne
,因此主线程调用
Reset
,然后
beginacept
,使用事件,以便在连接发生时,在调用
Connect
方法之前不会再次调用
beginacept
。e、 g.
WaitOne
暂停线程,直到调用
Set
<调用code>Reset将事件的状态设置回Signaled,以便
WaitOne
将再次停止线程,以等待再次调用
Connect

就我个人而言,我不使用这种特殊模式。我从来没有见过对这种模式的意义的解释。如果
beginacept
循环和
Connect
方法之间存在某种共享状态,那么这可能是有意义的。但是,如文中所述,事件的使用不会保护任何状态。当我使用
beginacept
时,我只是不使用事件,我使用这样的代码一秒钟处理许多连接。使用事件无法防止一次连接过多的错误。坦率地说,使用异步方法并强制它有效地同步,这是行不通的

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

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); 
}
您的评论似乎表明您已经很好地掌握了这段特定的代码。您的“Step4”有点不正确,它不是等待
连接
方法结束,而是等待它开始(因为
设置
被称为第一行)。是的,“Step5”,即
Set
意味着它解除了
WaitOne
的阻塞,因此主线程调用
Reset
然后
Beg