Question

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

I'm trying to understand the ManualResetEvent in this asynchronus operation since I've never used it.

  • Step1. The SocketSrv is created to accept TCP connections and the type of sending and receving "commands" is stream.

  • Step2. The socket is binded with the ip,port and then we start listening for connections.

  • Step3. In the while loop :

    • The ManualResetEvent is Reset (I understand that the ManualResetEvent is a class which type is Boolean and indicates whenever a thread is busy or not).In this case , the event is always reset because if there's a connection made and another one is coming I need to reset it and start the "operation" again.

    • In the BeingAccept I'm being starting the asynchronous operation, the callback function which is executed and the IAsyncResult argument which will become the "socket".

  • Step4. The ResetEvent is now Waiting blocking the current thread and waiting for the handler in the connection method to be ended so it can finish initializing the current connection.

  • Step5. In the connection thread the ResetEvent sets the signal true which means... well I don't know what does it means. I think it tells to the ResetEvent to unblock the main thread.

In the 'con' socket I'm getting the AsyncState. I have no idea what does it means.

In the handler socket I'm telling the ResetEvent that the connection was made.

Things being said, could someone tell me if what I've said is true/wrong and why?

Was it helpful?

Solution

The event is used so that when a connection occurs BeginAccept won't be called again until the Connect method has been invoked. e.g. WaitOne halts the thread until Set is called. Reset is called to set the state of the event back to signalled so that WaitOne will halt the thread again so that it will wait for Connect to be called again.

Personally, I don't use this particular pattern. I've never seen an explanation of the point of this pattern. If there were some shared state between the BeginAccept loop and the Connect method, it might make sense. But, as written no state is guarded by use of the event. When I use BeginAccept I simply don't use an event, and I've used code like this to deal with many connections a second. Use of the event will do nothing to prevent errors with too many connections at a time. And quite frankly, to use an asynchronous method and force it to effectively be synchronous defeats the purpose.

The AysncState, from the point of view of BeginAccept, is simply opaque data. It's the "state" that is used for that particular async operation. This "state" is application-specific. You use whatever you need when you want to process a connection asynchronously. In the case of the BeginAccept callback, you usually want to do something with the server socket and it's passed in for the state so you have access to it to call EndAccept. Since SocketSrv is a member field, you don't really need to do this, you could do this instead:

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

Your comments seem to suggest you have a good grasp of this particular bit of code. Your "Step4" is a bit off, it's not waiting for the Connection method to end, just for it to start (since Set is called as the first line). And yes, "Step5", the Set means it unblocks the WaitOne so the main thread call call Reset then BeginAccept.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top