嗅探 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);
}
}
对比
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 和端口。
有任何网络大师想参与进来吗?
谢谢!