我正在尝试使用线程同时从多个IP捕获网络数据包,但是我得到了这个异常“由于系统缺少足够的缓冲区空间或因为队列缺乏,因此无法执行套接字上的操作全”。我是线程和套接字的新手。例外来自“ mainSocket.BeginReceive(_data,0,_data.Length,SocketFlags.None,OnReceive,null); ”
IPHostEntry HosyEntry = Dns.GetHostEntry((Dns.GetHostName()));
if (HosyEntry.AddressList.Length > 0)
{
foreach (IPAddress ip in HosyEntry.AddressList)
{
if (ip.IsIPv6LinkLocal == false)
{
SetIp ipAdd = new SetIp();
ipAdd.SetIpAdd(ip);
}
}
}
class SetIp
{
private Socket mainSocket;
private byte[] _data = new byte[4096];
public void SetIpAdd(IPAddress address)
{
mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
mainSocket.Bind(new IPEndPoint(address, 0));
Thread MyThread = new Thread(new ThreadStart(() =>{
while (true)
{
mainSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);
byte[] byTrue = new byte[] { 1, 0, 0, 0 };
byte[] byOut = new byte[] { 1, 0, 0, 0 };
mainSocket.IOControl(IOControlCode.ReceiveAll, byTrue, byOut);
mainSocket.BeginReceive(_data, 0, _data.Length, SocketFlags.None, OnReceive, null);
} }));
MyThread.Start();
}
private void OnReceive(IAsyncResult ar)
{
var received = mainSocket.EndReceive(ar);
Parse(_data, received);
mainSocket.BeginReceive(_data, 0, _data.Length, SocketFlags.None, OnReceive, null);
}
private void Parse(byte[] data, int size)
{
IPHeader ipHeader = new IPHeader(data, size);
Console.WriteLine( ipHeader.SourceIP.ToString());
}
答案 0 :(得分:1)
您在热循环中无限次地呼叫BeginReceive
。这导致无限多的IO排队。
您可能希望使用同步IO,因为它更易于使用。或者,只发出最后一个完成的下一个读物。
答案 1 :(得分:1)
使用Receive方法代替BeginReceive方法。
mainSocket.Receive(byteData, 0, byteData.Length, SocketFlags.None);
ParseData(byteData, byteData.Length);