C # UDP Socket: Получить адрес получателя

У меня есть класс асинхронного UDP-сервера с сокетом, привязанным к IPAddress.Any, и я хотел бы знать, на какой IPAddress был отправлен полученный пакет (... или получил). Кажется, я не могу просто использовать свойство Socket.LocalEndPoint, так как оно всегда возвращает 0.0.0.0 (что имеет смысл, поскольку оно привязано к этому ...).

Вот интересные части кода, который я в настоящее время используется:

private Socket udpSock;
private byte[] buffer;
public void Starter(){
    //Setup the socket and message buffer
    udpSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    udpSock.Bind(new IPEndPoint(IPAddress.Any, 12345));
    buffer = new byte[1024];

    //Start listening for a new message.
    EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
    udpSock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, udpSock);
}

private void DoReceiveFrom(IAsyncResult iar){
    //Get the received message.
    Socket recvSock = (Socket)iar.AsyncState;
    EndPoint clientEP = new IPEndPoint(IPAddress.Any, 0);
    int msgLen = recvSock.EndReceiveFrom(iar, ref clientEP);
    byte[] localMsg = new byte[msgLen];
    Array.Copy(buffer, localMsg, msgLen);

    //Start listening for a new message.
    EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
    udpSock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, udpSock);

    //Handle the received message
    Console.WriteLine("Recieved {0} bytes from {1}:{2} to {3}:{4}",
                      msgLen,
                      ((IPEndPoint)clientEP).Address,
                      ((IPEndPoint)clientEP).Port,
                      ((IPEndPoint)recvSock.LocalEndPoint).Address,
                      ((IPEndPoint)recvSock.LocalEndPoint).Port);
    //Do other, more interesting, things with the received message.
}

Как упоминалось ранее, это всегда выводит строку вида:

Получено 32 байта от 127.0.0.1:1678 до 0.0.0.0:12345

И я бы хотел, чтобы это было что-то вроде:

Получено 32 байта от 127.0.0.1:1678 до 127.0.0.1:12345

Заранее спасибо за любые идеи по этому поводу! Я хочу знать, на какой IP-адрес был отправлен полученный пакет (... или получен). Кажется, я не могу просто использовать свойство Socket.LocalEndPoint, так как оно всегда возвращает 0.0.0.0 (что имеет смысл, поскольку оно привязано к этому ...).

Вот интересные части кода, который я в настоящее время используется:

private Socket udpSock;
private byte[] buffer;
public void Starter(){
    //Setup the socket and message buffer
    udpSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    udpSock.Bind(new IPEndPoint(IPAddress.Any, 12345));
    buffer = new byte[1024];

    //Start listening for a new message.
    EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
    udpSock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, udpSock);
}

private void DoReceiveFrom(IAsyncResult iar){
    //Get the received message.
    Socket recvSock = (Socket)iar.AsyncState;
    EndPoint clientEP = new IPEndPoint(IPAddress.Any, 0);
    int msgLen = recvSock.EndReceiveFrom(iar, ref clientEP);
    byte[] localMsg = new byte[msgLen];
    Array.Copy(buffer, localMsg, msgLen);

    //Start listening for a new message.
    EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
    udpSock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, udpSock);

    //Handle the received message
    Console.WriteLine("Recieved {0} bytes from {1}:{2} to {3}:{4}",
                      msgLen,
                      ((IPEndPoint)clientEP).Address,
                      ((IPEndPoint)clientEP).Port,
                      ((IPEndPoint)recvSock.LocalEndPoint).Address,
                      ((IPEndPoint)recvSock.LocalEndPoint).Port);
    //Do other, more interesting, things with the received message.
}

Как упоминалось ранее, это всегда выводит строку вида:

Получено 32 байта от 127.0.0.1:1678 до 0.0.0.0:12345

И я бы хотел, чтобы это было что-то вроде:

Получено 32 байта от 127.0.0.1:1678 до 127.0.0.1:12345

Заранее спасибо за любые идеи по этому поводу! Я хочу знать, на какой IP-адрес был отправлен полученный пакет (... или получен). Кажется, я не могу просто использовать свойство Socket.LocalEndPoint, так как оно всегда возвращает 0.0.0.0 (что имеет смысл, поскольку оно привязано к этому ...).

Вот интересные части кода, который я в настоящее время используется:

private Socket udpSock;
private byte[] buffer;
public void Starter(){
    //Setup the socket and message buffer
    udpSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    udpSock.Bind(new IPEndPoint(IPAddress.Any, 12345));
    buffer = new byte[1024];

    //Start listening for a new message.
    EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
    udpSock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, udpSock);
}

private void DoReceiveFrom(IAsyncResult iar){
    //Get the received message.
    Socket recvSock = (Socket)iar.AsyncState;
    EndPoint clientEP = new IPEndPoint(IPAddress.Any, 0);
    int msgLen = recvSock.EndReceiveFrom(iar, ref clientEP);
    byte[] localMsg = new byte[msgLen];
    Array.Copy(buffer, localMsg, msgLen);

    //Start listening for a new message.
    EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
    udpSock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, udpSock);

    //Handle the received message
    Console.WriteLine("Recieved {0} bytes from {1}:{2} to {3}:{4}",
                      msgLen,
                      ((IPEndPoint)clientEP).Address,
                      ((IPEndPoint)clientEP).Port,
                      ((IPEndPoint)recvSock.LocalEndPoint).Address,
                      ((IPEndPoint)recvSock.LocalEndPoint).Port);
    //Do other, more interesting, things with the received message.
}

Как упоминалось ранее, это всегда выводит строку вида:

Получено 32 байта от 127.0.0.1:1678 до 0.0.0.0:12345

И я бы хотел, чтобы это было что-то вроде:

Получено 32 байта от 127.0.0.1:1678 до 127.0.0.1:12345

Заранее спасибо за любые идеи по этому поводу! --Adam

UPDATE

Что ж, я нашел решение, хотя оно мне не нравится ... По сути, вместо того, чтобы открывать единственный сокет udp, привязанный к IPAddress.Any, я создаю уникальный сокет для каждого доступного Айпи адрес. Итак, новая функция Starter выглядит так:

public void Starter(){
    buffer = new byte[1024];

    //create a new socket and start listening on the loopback address.
    Socket lSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    lSock.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345);

    EndPoint ncEP = new IPEndPoint(IPAddress.Any, 0);
    lSock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref ncEP, DoReceiveFrom, lSock);

    //create a new socket and start listening on each IPAddress in the Dns host.
    foreach(IPAddress addr in Dns.GetHostEntry(Dns.GetHostName()).AddressList){
        if(addr.AddressFamily != AddressFamily.InterNetwork) continue; //Skip all but IPv4 addresses.

        Socket s = new Socket(addr.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
        s.Bind(new IPEndPoint(addr, 12345));

        EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
        s.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, s);
    }
}

Это просто для иллюстрации концепции, самая большая проблема с этим кодом, как есть, заключается в том, что каждый сокет пытается использовать один и тот же буфер ... что обычно является плохой идеей. ..

Для этого должно быть лучшее решение; Я имею в виду, что источник и место назначения являются частью заголовка пакета UDP! Ну ладно, я пойду с этим, пока не будет что-нибудь получше.

18
задан chezy525 12 November 2010 в 00:41
поделиться