从UDP连接中获取客户端IP(C#)

3

我目前拥有一个服务器应用程序,它在端口上监听UDP数据包。当服务器接收到数据包时,会正确地接收并处理它。是否有办法获取数据包来自哪个IP地址?

下面是我创建套接字的方式:

this.UDPListener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, Port);
this.UDPListener.Bind(endPoint);

SocketAsyncEventArgs socketEventArgs = new SocketAsyncEventArgs(); 
socketEventArgs.SetBuffer(this.ReceiveBuffer, 0, this.ReceiveBuffer.Length);
socketEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceive);
if (!this.UDPListener.ReceiveAsync(socketEventArgs))
    ThreadPool.QueueUserWorkItem(new WaitCallback((Object o) => this.OnReceive(this, socketEventArgs)));

当OnReceive被调用时,没有任何内容包含消息来自哪个IP的信息。我已经查看了SocketAsyncEventArgs,但是我只能看到监听的IP地址。

编辑:

这是我最终采取的措施。

this.UDPListener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
this.UDPListener.Bind(new IPEndPoint(IPAddress.Any, Port));

EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
this.UDPListener.BeginReceiveFrom(ReceiveBuffer, 0, ReceiveBuffer.Length, SocketFlags.None, ref remoteEndPoint, OnReceive, this.UDPListener);

然后在OnReceive中,以下是如何获取数据和信息的方法。
//Get the received message.
Socket receiveSocket = (Socket)AsyncResult.AsyncState;
EndPoint clientEndPoint = new IPEndPoint(IPAddress.Any, 0);
int udpMessageLength = receiveSocket.EndReceiveFrom(AsyncResult, ref clientEndPoint);
byte[] udpMessage = new byte[udpMessageLength];
Array.Copy(ReceiveBuffer, udpMessage, udpMessageLength);

//Start listening for a new message.
EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, Int32.Parse(((IPEndPoint)receiveSocket.LocalEndPoint).Port.ToString()));
this.UDPListener.BeginReceiveFrom(ReceiveBuffer, 0, ReceiveBuffer.Length, SocketFlags.None, ref remoteEndPoint, OnReceive, this.UDPListener);

//Handle the received message
Debug.WriteLine("Recieved {0} bytes from {1}:{2} to {3}:{4}", udpMessageLength, ((IPEndPoint)clientEndPoint).Address, ((IPEndPoint)clientEndPoint).Port, ((IPEndPoint)receiveSocket.LocalEndPoint).Address, ((IPEndPoint)receiveSocket.LocalEndPoint).Port);

这里有一个很好的答案:https://dev59.com/T2855IYBdhLWcg3wyniC#5795658 - Stephen Kennedy
3个回答

6

我不了解 UdpClient,但是如果你直接使用 Socket 类,你可以调用 .ReceiveFrom(byte[], ref EndPoint) 方法,并通过第二个参数接收远程地址。


0
你需要检查参数中的ReceiveMessageFromPacketInfo字段。
    void OnReceive(object sender, SocketAsyncEventArgs e)
    {
        var info = e.ReceiveMessageFromPacketInfo;
        byte[] address = info.Address.GetAddressBytes();
    }

1
我的info.Address为空,原因不明。 - thecaptain0220
奇怪;如果您将 e.ReceiveMessageFromPacketInfo 替换为 (IPEndPoint)e.RemoteEndPoint,那么 Address 会是什么空值? - Greg Buehler
e.RemoteEndPoint也是空的。我不确定你是否只是不能用UDP做到这一点,或者其他什么原因。看起来那个信息应该在某个地方。 - thecaptain0220
1
请参见:https://dev59.com/T2855IYBdhLWcg3wyniC - Greg Buehler

0

不行,还有 null。这就是我开始寻找的地方,不确定为什么它没有出现。 - thecaptain0220

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