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?
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
.