簡體   English   中英

C#獲取UDP服務器套接字從中接收數據的客戶端的IP地址

[英]C# Getting the IP Address of the client which the UDP server socket received data from

我有一個非常奇怪的問題。 我無法找到我的服務器從中接收數據的客戶端的IP地址。 下面是我的UDP Listener類。

IPPacketInformation不包含IP。 我在我的EndReceiveMessageFrom參考clientEndPoint既不。

當我

Console.Writeline(((IPEndPoint)clientEndPoint).Address); 

我得到了服務器的IP地址。 我把服務器托管在我自己的機器上,所以我得到了自己的IP地址。 當我嘗試訪問clientEndPoint.remoteEndPoint時,它會拋出一個錯誤,因為套接字未連接(由於是UDP)。

所以基本上,來自外部IP的客戶端能夠發送數據,但我無法回答客戶端,因為我無法檢索它的IP。 任何幫助表示贊賞!

public class UdpListener
{
    private Socket s;
    public byte[] ReceiveBuffer = new byte[2048];

    public UdpListener()
    {
        s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true);
        s.Bind(new IPEndPoint(IPAddress.Any, 36200));
    }

    public void Listen()
    {
        try
        {
            EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
            s.BeginReceiveMessageFrom(ReceiveBuffer, 0, ReceiveBuffer.Length, SocketFlags.None, ref remoteEndPoint, Recv, s);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
            throw;
        }
    }

    private void Recv(IAsyncResult res)
    {
        try
        {
            Socket receiveSocket = (Socket)res.AsyncState;

            EndPoint clientEndPoint = new IPEndPoint(IPAddress.Any, 0);
            IPPacketInformation packetInfo;
            SocketFlags flags = SocketFlags.None;
            int udpMessageLength = receiveSocket.EndReceiveMessageFrom(res, ref flags, ref clientEndPoint, out packetInfo);
            byte[] udpMessage = new byte[udpMessageLength];
            Array.Copy(ReceiveBuffer, udpMessage, udpMessageLength);

            Console.WriteLine(
                "{0} bytes received from {1} to {2}",
                ReceiveBuffer,
                clientEndPoint,
                packetInfo.Address
            );

            EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, ((IPEndPoint)receiveSocket.LocalEndPoint).Port);
            s.BeginReceiveMessageFrom(ReceiveBuffer, 0, ReceiveBuffer.Length, SocketFlags.None, ref remoteEndPoint, Recv, s);

            //Process data
            RaiseDataReceived(new ReceivedDataArgs(packetInfo.Address, ((IPEndPoint)clientEndPoint).Port, udpMessage));
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
            throw;
        }
    }

    public delegate void DataReceived(ReceivedDataArgs args);

    public event DataReceived DataReceivedEvent;

    private void RaiseDataReceived(ReceivedDataArgs args)
    {
        DataReceivedEvent?.Invoke(args);
    }
}

我試圖禁用我的防火牆,但這沒有幫助。 我還在路由器上完成了端口轉發,因此我可以從外部客戶端接收數據。

編輯澄清問題:

服務器托管在我的機器后面的NAT公共IP 214.214.214.214。

客戶端是另一台機器,在公共IP 910.910.910.910的另一台NAT后面。

客戶端向服務器發送消息,服務器接收消息並能夠讀取內容。 當服務器獲取客戶端的IPEndPoint時,顯示的IP為214.214.214.214(服務器的IP, 而不是客戶端

編輯也許我應該說我無法從外部網絡上的客戶端接收消息,直到我從我的ISP訂購了“動態IP”。 仍然無法獲得源的公共IP。

編輯當使用Wireshark並嗅探從外部客戶端發送到我的服務器的數據包時,我也可以看到它是錯誤的src IP。 在下圖中,src IP是我的服務器IP,而不是發送數據的客戶端的IP。

在此輸入圖像描述

經過幾天閱讀我可能在路由器,網絡和寫入Receive,ReceiveFrom,ReceiveMessageFrom,BeginReceive,BeginReceiveFrom,BeginReceiveMessageFromReceiveAsync的不同示例的所有內容 - 我已經解決了我的問題。

我換了路由器。 我現在可以使用非常舊的路由器獲取外部客戶端的源IP。 我以前使用的路由器是一個新的Docsis 3.1。

為什么它適用於舊路由器,我不知道,但由於某種原因,Docsis 3.1在將UDP消息發送到我的機器之前將源IP更改為其自己的IP。

使用UdpClient類,您可以在接收消息時實際檢索遠程端點。

我使用了以下解決方案來解決此任務:

public void StartServer()
{
    var udpServer = new UdpClient(new IPEndPoint(IPAddress.Any, ConnectionInformation.DETECTION_PORT));
    udpServer.BeginReceive(new AsyncCallback(detectionCallback), udpServer);
}

private void detectionCallback(IAsyncResult ar)
{
    var client = (ar.AsyncState as UdpClient);
    if (client.Client == null) return;

    var endPoint = new IPEndPoint(IPAddress.Any, ConnectionInformation.DETECTION_PORT);
    var bytes = client.EndReceive(ar, ref endPoint);

    Debug.WriteLine($"Detection request from: {endPoint}");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM