【问题标题】:Multi-Threading on sockets C#套接字上的多线程 C#
【发布时间】:2014-05-01 14:49:31
【问题描述】:

我正在尝试使用线程同时从多个 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());
    }

【问题讨论】:

  • 请显示_data 初始化它的行。
  • @DavidHaney - 它在 SetIpAdd 方法之上被初始化。
  • 对,我要求您将其显示为代码的一部分。 :)
  • @DavidHaney 我编辑了代码
  • 一般来说,当答案解决了问题时,编辑问题是不合适的。现在,当您编辑代码以解决问题时,您的原始问题不再适用。撤消您的编辑并发布单独的答案可能是个好主意,以免造成混乱。

标签: c# multithreading sockets


【解决方案1】:

您在热循环中无限频繁地调用BeginReceive。这会导致无限多的 IO 排队。

您可能想使用同步 IO,因为它使用起来更简单。或者,仅在最后一个阅读完成后发出下一个阅读。

【讨论】:

  • 是的 - 您必须发出一个 beginreceive 然后等待回电。但是您正在执行多个线程:同步接收要简单得多-此调用将阻塞直到有数据
  • @usr 我没明白你在说什么,因为我是新手,如果你能给我看一个教程或代码 sn-p 它是如何完成的,那就太好了。
  • 网络上到处都有TCP服务器的教程。您正在运行一个无限循环。而那个循环从不等待任何东西。它每秒调用 BeginReceive 数百万次。相反,您可能只想在前一个接收完成后开始下一个接收。明白了吗?
  • @usr 我想我明白了。谢谢。
  • @usr 我想同时从 IP 地址捕获数据包。所以我无法完成一个 IP 并转到下一个。我该怎么做?
【解决方案2】:

使用 Receive 方法而不是 BeginReceive 方法。

    mainSocket.Receive(byteData, 0, byteData.Length, SocketFlags.None);

                ParseData(byteData, byteData.Length);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-16
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    • 1970-01-01
    相关资源
    最近更新 更多