Socket.Begin接收有关循环与递归调用的问题

时间:2018-10-16 18:47:59

标签: .net sockets networking beginreceive

嗅探NIC卡上的IP时,Socket.BeginReceive是否不会自动发出呼叫以捕获所有传入IP数据包的信号?为什么将它放在while(true)循环中而不是递归调用会产生更多结果?

我的意思是BeginReceive应该是一个异步无阻塞调用,因此,只需调用一次就足以继续在该套接字上侦听了?

但这似乎不是正确的解释,因为将其放入while(true)循环中会产生更多结果,然后再从回调函数中递归调用它。

而且,如果将其放入while(true)循环中是有效的(基本上是轮询该IP地址以获取传入请求),那么此方法是否有可能还会丢失一些信息?因此,它在硬件级别上没有真正的约束力吗?

例如为什么这样做:

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

// ============================================= =========================== 更新 // ================================================ =======================

经过大量的研究和阅读,看来.BeginReceive的递归调用仅在有特定的客户希望从中发送请求时才使用。

但是,由于.EndReceive函数在所有数据输入之前一直处于阻塞状态,因此我真的不确定这是否仍然是正确的方法,而且我坚信以这种方式递归实现的任何人都可能会丢失传入的数据,因为.EndReceive可能会阻塞,直到来自始发.BeginReceive调用的所有原始消息都完全进入?

我读得越多,看起来while(true)方法就越可靠。

实际上,.BeginReceive / .EndReceive更像是对特定IP地址进行异步轮询以获取信息的方案。我不确定这些方法是否真的阻止了通过NIC卡中特定IP的消息传输,因为看起来这些方法可能只是“监听”了该特定IP和端口。

任何网络专家都想参与其中吗?

谢谢!

0 个答案:

没有答案
相关问题