C# - 使用receiveFrom获取多播数据包的源IP

3

大家好

问题:

我正在尝试获取多播数据包的源IP,但是我得到的都是0.0.0.0:80。

我尝试过的方法:

我尝试了这些网站上显示的方法,不确定我是否正确实现了,但是所有方法都返回相同的IP地址,即0.0.0.0,此帖子此帖子

这两个链接都提到使用socket.recieveFrom()或socket.BeginRecieveMessageFrom()代替socket.recieve()

        private void recieveText()
        {
            //initialise multicast group and bind to interface
            Socket _listener_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, _PORT);
            _listener_socket.Bind(ipep);
            IPAddress localip = IPAddress.Parse("224.5.6.7");
            _listener_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(localip, IPAddress.Any));

            //recieve data to multicast group
            while (_listener_socket.IsBound)
            {
                updateLabel("listening...");
                byte[] b = new byte[1024];
                updateLabel("message recieved");
                updateRedBox("\n---------------------------------\n New Message :\n");
                EndPoint IPEPoint = (EndPoint)ipep;
                _listener_socket.BeginReceiveMessageFrom(b, 0, b.Length, 0, ref IPEPoint, null, null);
                updateRedBox(IPEPoint.ToString());
                char[] chars = new char[b.Length / sizeof(char)];
                System.Buffer.BlockCopy(b, 0, chars, 0, b.Length);

                string t = new string(chars).Trim();
                updateRedBox(t);
                updateRedBox("\n----------------------------------\n");
            }
        }

2
BeginReceiveMessageFrom 是一个 异步 操作。当它返回时,并不一定已经完成了任何事情。如果你需要异步,请在访问该值之前等待它完成。否则,切换到同步的 ReceiveMessageFrom 。不能保证这会修复你的问题,但是目前代码存在明显的错误。 - Damien_The_Unbeliever
@Damien_The_Unbeliever 感谢提示,我会更改的:p,什么时候使用BeginRecieveMessageFrom()比较合适? - CybeX
1个回答

1

在调用异步的 BeginReceiveMessageFrom 后,你应该使用同步的 ReceiveMessageFrom 调用或者调用 EndReceiveMessageFrom

private void recieveText()
{
    //initialise multicast group and bind to interface
    Socket _listener_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    IPEndPoint ipep = new IPEndPoint(IPAddress.Any, _PORT);
    _listener_socket.Bind(ipep);
    IPAddress localip = IPAddress.Parse("224.5.6.7");
    _listener_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(localip, IPAddress.Any));

    //recieve data to multicast group
    while (_listener_socket.IsBound)
    {
        updateLabel("listening...");
        byte[] b = new byte[1024];
        updateLabel("message recieved");
        updateRedBox("\n---------------------------------\n New Message :\n");
        EndPoint IPEPoint = (EndPoint)ipep;
        var res = _listener_socket.BeginReceiveMessageFrom(b, 0, b.Length, 0, ref IPEPoint, null, null);
        SocketFlags flags = SocketFlags.None;
        IPPacketInformation packetInfo;
        _listener_socket.EndReceiveMessageFrom(res, ref flags, ref IPEPoint, out packetInfo);
        updateRedBox(IPEPoint.ToString());
        char[] chars = new char[b.Length / sizeof(char)];
        System.Buffer.BlockCopy(b, 0, chars, 0, b.Length);

        string t = new string(chars).Trim();
        updateRedBox(t);
        updateRedBox("\n----------------------------------\n");
    }
}

请看我添加的BeginReceiveMessageFrom后面的3行代码。除了远程IP地址外,您可以使用标志来确定此消息是否作为多播消息接收,并且多播组IP地址可以从packetInfo中获取。


你,先生,真是个天才。我研究了一下异步接收数据的方法,但对回调函数不太确定,它到底是做什么用的,有什么作用(回调函数通常应包含哪些内容)? - CybeX
@KGCybeX 你应该了解一下异步编程模型。基本思想是:BeginXXX 调用会启动一个异步操作。为了在操作终止时得到通知,你应该使用回调委托进行注册。一旦你不能再异步地进行操作,就可以调用 EndXXX 方法来潜在地阻塞并检索操作 XXX 的结果。 - Vikhram

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接