Peter Sung
Peter Sung

Reputation: 1

Socket.BeginReceive question regarding loop vs recursive calling

When sniffing an IP on a NIC card, does Socket.BeginReceive not automatically signal a call to capture all incoming IP packets? Why does putting this in a while(true) loop yield more results vs. recursively calling it?

I mean BeginReceive is supposed to be an Asynchronous non-block call, so calling it once would be enough to continue listening on that socket yes?

But this doesn't seems to be the right interpretation because putting this in a while(true) loop yields more results then calling it recursively from the callback function.

And also, if puttting this in a while(true) loop is valid, which is basically polling that IP address for incoming requests, then isn't it possible that this method still might lose some information? So its not really binding on the hardware level?

For example why do this:

while (true)
{
    //sets the byte array buffer, byte offset (start), byte size, etc...
    socket.BeginReceive(p_PacketBuffer, 0, p_PacketBufferSize, SocketFlags.None, new AsyncCallback(OnReceive), this);

     while (socket.Available == 0)
     {
         Thread.Sleep(1);
     }
}

private void OnReceive(IAsyncResult ar)
{
    try
    {
        //read the data from client socket
        int bytesRead = socket.EndReceive(ar);
        if (bytesRead > 0)
        {
            var objState = (Sentry.Adapters)ar.AsyncState;
            Task.Run(() =>
            {
                //clear the array from current state object
                PacketHandler pkHandler = new PacketHandler(packetRecEvent, ref objState.p_PacketBuffer);
                Array.Clear(objState.p_PacketBuffer, 0, objState.p_PacketBuffer.Length);
            });
        }
    }
    catch (Exception ex)
    {
        Logging.Add("INFO Socket Error: " + ex.Message);
    }
}

vs

socket.BeginReceive(p_PacketBuffer, 0, p_PacketBufferSize, SocketFlags.None, new AsyncCallback(OnReceive), this);

private void OnReceive(IAsyncResult ar)
{
    try
    {
        //read the data from client socket
        int bytesRead = socket.EndReceive(ar);
        if (bytesRead > 0)
        {
            var objState = (Sentry.Adapters)ar.AsyncState;
            Task.Run(() =>
            {
                //clear the array from current state object
                PacketHandler pkHandler = new PacketHandler(packetRecEvent, ref objState.p_PacketBuffer);
                Array.Clear(objState.p_PacketBuffer, 0, objState.p_PacketBuffer.Length);
            });

            socket.BeginReceive(p_PacketBuffer, 0, p_PacketBufferSize, SocketFlags.None, new AsyncCallback(OnReceive), this);
        }
    }
    catch (Exception ex)
    {
        Logging.Add("INFO Socket Error: " + ex.Message);
    }
}

//========================================================================= UPDATE //=========================================================================

From doing a lot of research and reading, it looks like the recursive calling of .BeginReceive is used only when there is a specific client your expecting a request from and sending to.

But since the .EndReceive function is blocking until all data is coming in, I'm really not sure if this is the correct way still and I'm convinced that anyone who implemented recursively this way may be losing incoming data as the .EndReceive may block until all the original message from the originating .BeginReceive call has fully come in?

The more I read this, it looks like the while(true) method is the more reliable method.

And truly the .BeginReceive/.EndReceive is more like an asynchronous polling scheme on a specific IP address to get the information coming through. I'm not quite sure if these methods actually block the transmission of the messages through the specific IP in the NIC card, as it looks like these methods might just be "listening in" to that specific IP and Port(s).

Any Networking Guru wanna weigh in on this?

thanks!

Upvotes: 0

Views: 318

Answers (0)

Related Questions