不通过网络发送的多播数据包返回

时间:2016-01-11 19:09:45

标签: c# sockets networking network-programming

美好的一天。

我的软件使用多播组发送消息,但是应用程序充当客户端和服务器,因此它发送udp数据包并接收它们。

使用包含2 000个字符的文本进行测试。

我创建了一个包含byte [1024]数组的队列,其中包含需要发送的数据。

问题:

问题在于接收这些多播数据包,在发送的5个数据包中,我主要只接收1个,定期接收2个等等,并且有几次我收到所有这些数据包。

发送和接收结果如下:

  • 发送的数据包:发送1,2,3,4,5
  • 返回的数据包:1,2,3,4,F(F是序列中的最后一个数据包,即关闭数据包)
  

12345   134F

     

12345   1F

     

12345   134F

     

12345   14F

     

12345   1F

     

12345   1F

     

12345   1

     

12345   1

     

12345   1

     

12345   1234F

     

12345   1F

     

12345   1

     

12345   1

     

12345   1

     

12345   14F

     

12345   1F

     

12345   1F

     

12345   1

     

12345   1

     

12345   1

     

12345   1F

     

12345   1

按如下方式发送多播数据包:

        Socket _listener_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        foreach (IPAddress localIP in Dns.GetHostAddresses(Dns.GetHostName()).Where(i => i.AddressFamily == AddressFamily.InterNetwork))
        {
            //handle image and files                
            _listener_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(_MultiIP, localIP));
            _listener_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 1);
            _listener_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            _listener_socket.MulticastLoopback = true;
            _listener_socket.Connect(new IPEndPoint(_MultiIP, _PORT));
            while (count > 0)
            {      
                count--;              
                byte[] temp = (byte[])(MSGS_TO_SEND.Dequeue());
                _listener_socket.Send(temp, _BYTE_BUFFER_SIZE, SocketFlags.None);
                MSGS_TO_SEND.Enqueue(temp);
            }
        }
        _listener_socket.Close();

一个线程用于接收数据包并将它们添加到队列进行处理,第二个线程用于处理。 2个线程的原因可能是接收线程中的处理太多导致了这个"数据包丢失",但不幸的是它没有解决问题

接收主题:

//initialise multicast group and bind to interface
        Socket _sender_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        IPEndPoint ipep = new IPEndPoint(IPAddress.Any, _PORT);
        _sender_socket.Bind(ipep);
        IPAddress localip = _MultiIP;
        _sender_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(localip, IPAddress.Any));
        Q_RECIEVE = new Queue<char[]>();
        while (_sender_socket.IsBound && !bStop)
        {
            byte[] b = new byte[_BYTE_BUFFER_SIZE];
            _sender_socket.Receive(b);
            char[] chars = new char[_BYTE_BUFFER_SIZE];
            System.Buffer.BlockCopy(b, 0, chars, 0, b.Length);
            Q_RECIEVE.Enqueue(chars);
        }

1 个答案:

答案 0 :(得分:1)

它们有可靠的UDP协议和库。我之前使用过UDT(http://udt.sourceforge.net/)并且工作正常。我不知道它的C#包装器,但可能有一个或另一个可靠的UDP C#实现。

除此之外,还有其他一些建议:

  1. 多播在交换机上几乎是有问题的。如果可以,尝试更改它们。有时它也可能是路由器上的问题,因此,如果可能的话,您也可以尝试更改它们。

  2. 尝试发送更少的数据包(或更少)。如果你的年龄低于1500,数据包长度不应该是一个问题,但是,你也可以尝试减少长度。

  3. 为了确保您不会因某些原因丢失代码中的数据包,请使用数据包嗅探器并查看数据包是否实际到达目标计算机。 WireShark有一个足够好的GUI,但有几个基于GUI和CLI的GUI。