C# 从UDP消息中获取发送者地址

发布于 2024-09-16 20:47:50 字数 2142 浏览 5 评论 0原文

我有一个嵌入式以太网接口 (Lantronix XPort),它用其标识信息响应 UDP 广播。

我能够多播“魔术包”并且侦听器正确接收数据报,但是我还需要找出发送该响应数据报的 IP 地址。如果是 TCP,我会执行 socket.RemoteEndPoint,但这在应用于 UDP 套接字时会引发异常。

public class Program
{
    public static void Main(string[] args)
    {
        // magic packet
        byte[] magicPacket = new byte[4] { 0, 0, 0, 0xf6 };

        // set up listener for response
        Socket sendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

        // EDIT: Also, had to add this to for it to broadcast correctly
        sendSocket.EnableBroadcast = true;
        IPEndPoint listen_ep = new IPEndPoint(IPAddress.Any, 0);
        sendSocket.Bind(listen_ep);

        // set up broadcast message
        EndPoint send_ep = new IPEndPoint(IPAddress.Parse("192.168.255.255"), 30718);
        sendSocket.SendTo(magicPacket, magicPacket.Length, SocketFlags.None, send_ep);

        DateTime dtStart = DateTime.Now;
        while (true)
        {
            if (sendSocket.Available > 0)
            {
                byte[] data = new byte[2048];
                // throws SocketException
                //IPEndPoint ip = sendSocket.RemoteEndPoint as IPEndPoint;
                sendSocket.Receive(data, SocketFlags.None);
                if (data.Length > 4)
                {
                    PrintDevice(data);
                }
            }

            if (DateTime.Now > dtStart.AddSeconds(5))
            {
                break;
            }

            Console.WriteLine(".");

            Thread.Sleep(100);
        }

        // wait for keypress to quit
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
} 

有什么想法吗?是否有更好的策略来读取响应数据报,让我确定远程 IP 地址?

编辑:

正如往常一样,当我在 SO 上发帖的那一刻,我突然清醒了。

事实证明我可以这样做:

                EndPoint remote_ep = new IPEndPoint(IPAddress.Any, 0);
                // Use ReceiveFrom instead of Receieve
                //sendSocket.Receive(data, SocketFlags.None);
                sendSocket.ReceiveFrom(data, ref remote_ep);

并且remote_ep现在包含远程端点信息!

I have an embedded Ethernet interface (Lantronix XPort) that responds to a UDP broadcast with its identifying information.

I am able to multicast the "magic packet" and datagrams are received by the listener correctly, however I also need to find out what IP Address send that response datagram. If it were TCP, I would do socket.RemoteEndPoint, but that throws an exception when applied to a UDP socket.

public class Program
{
    public static void Main(string[] args)
    {
        // magic packet
        byte[] magicPacket = new byte[4] { 0, 0, 0, 0xf6 };

        // set up listener for response
        Socket sendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

        // EDIT: Also, had to add this to for it to broadcast correctly
        sendSocket.EnableBroadcast = true;
        IPEndPoint listen_ep = new IPEndPoint(IPAddress.Any, 0);
        sendSocket.Bind(listen_ep);

        // set up broadcast message
        EndPoint send_ep = new IPEndPoint(IPAddress.Parse("192.168.255.255"), 30718);
        sendSocket.SendTo(magicPacket, magicPacket.Length, SocketFlags.None, send_ep);

        DateTime dtStart = DateTime.Now;
        while (true)
        {
            if (sendSocket.Available > 0)
            {
                byte[] data = new byte[2048];
                // throws SocketException
                //IPEndPoint ip = sendSocket.RemoteEndPoint as IPEndPoint;
                sendSocket.Receive(data, SocketFlags.None);
                if (data.Length > 4)
                {
                    PrintDevice(data);
                }
            }

            if (DateTime.Now > dtStart.AddSeconds(5))
            {
                break;
            }

            Console.WriteLine(".");

            Thread.Sleep(100);
        }

        // wait for keypress to quit
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
} 

Any thoughts? Is there a better strategy to reading the response datagrams that would let me ascertain the Remote IP Address?

EDIT:

As is typical, the minute I post on SO, a moment of clarity hits me.

Turns out I can just do this:

                EndPoint remote_ep = new IPEndPoint(IPAddress.Any, 0);
                // Use ReceiveFrom instead of Receieve
                //sendSocket.Receive(data, SocketFlags.None);
                sendSocket.ReceiveFrom(data, ref remote_ep);

And remote_ep now contains the remote endpoint information!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

陪我终i 2024-09-23 20:47:50

看一下 ReceiveFrom 而不是 Receive,它会让你传入对端点的引用。

Take a look at ReceiveFrom instead of Receive, it will let you pass in a reference to an Endpoint.

弱骨蛰伏 2024-09-23 20:47:50

异步套接字怎么样?我没有找到任何方法来获取远程IP地址。 (异步方法ReceiveFromAsync是我在wp8中唯一的选择)

What about Asynchronous socket?I didn't find any way to get the remote IP address. (Asynchronous method ReceiveFromAsync is my only option in wp8)

献世佛 2024-09-23 20:47:50

EndPoint remote_ep = new IPEndPoint(IPAddress.Any, 0); // 使用 ReceiveFrom 代替
sendSocket.Receive(数据, SocketFlags.None);
sendSocket.ReceiveFrom(数据,参考remote_ep);

我认为它适用于 IP,但不适用于端口号
如果您注意到

尝试将 0 更改为其他内容(例如 6530 4expl)

,系统将生成它的随机端口号,

有什么想法吗?

PS 有什么想法我可以在这里更改我的用户名....?

找到它:抽象类仅需要用于表示端口,它处于值中而不是输出中,

因为在此操作之前没有完成绑定,需要代表发送者的 ref EndPoint 。这意味着它用于显示发送者端口和 IP,而不是指定从何处获取通信。 EndPoint 实例化实际上只是一种形式,似乎无论如何都会被具有发件人地址的系统覆盖。我认为它必须与 UDP 协议的工作方式有关。
但总而言之,ref EndPoint 只显示您从哪里获取数据包,并且没有指定您希望通信的位置。

EndPoint remote_ep = new IPEndPoint(IPAddress.Any, 0); // Use ReceiveFrom instead of
sendSocket.Receive(data, SocketFlags.None);
sendSocket.ReceiveFrom(data, ref remote_ep);

i think it works for IP but it fails for port number
if you would notice

try chaging 0 to something else like 6530 4expl

it system will would generate it's random port number

Any ideas to why is it ?

P.S. Any ideas how can i change my user name here .... ?

FOUND IT : the abstract class only needed for representation of port it is in value not out

since there's no bind done before hand this operation ref EndPoint needed to represent the sender. Meaning that it is there to show senders port and IP not to specify from where to get the communication. And EndPoint instantiation is really just a formality seems like it is overriden by system with senders address anyway. I think it has to do somethign with the way UDP protocol works.
But all in all the ref EndPoint is there only shows where u got the packet from and only it does not specify where u want u'r commuicatino to be from.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文