使用IPAddress.Any获取客户端的IP

时间:2015-12-24 20:56:06

标签: c# .net sockets networking udp

我目前正在研究一个简单的udp客户端/服务器系统,我偶然发现了以下内容:当我尝试使用UdpClient在程序中获取IPEndPoint的IP(我使用IPAdress.Any获取)时,它可以正常工作得到以下结果(最上面的一个):

image

但是当我使用普通套接字而不是UdpClient时,它无法区分客户端/ IP(底部)。两者的代码如下所示。我想使用套接字的原因是因为使用相同的类来发送和接收(不是同一个实例)很方便,并使代码更容易理解。

第一

bool messageReceived = false;
bool done = false;
const int listenPort = 11000;
UdpClient listener = new UdpClient(listenPort);
IPEndPoint receiveEP = new IPEndPoint(IPAddress.Any, listenPort);
string[] adresses = new string[2];
public void ReceiveCallback(IAsyncResult ar)
{
    int id = 0;
    Byte[] receiveBytes = listener.EndReceive(ar, ref receiveEP);
    for (int i = 0; i < adresses.Length; i++)
    {
        if (adresses[i] == receiveEP.Address.ToString())
        {
            id = i;
            break;
        }
        else if (adresses[i] == null)
        {
            id = i;
            adresses[i] = receiveEP.Address.ToString();
            break;
        }
    }
    byte[] a= Encoding.ASCII.GetBytes("Is anybody there?");
    listener.Send(a, a.Length, receiveEP);
    Console.WriteLine("Received message from {0} (client {1}):",    adresses[id],id);
    string receiveString = Encoding.ASCII.GetString(receiveBytes);
    if (receiveString == "stop")
    {
        done = true;
    }
    Console.WriteLine("Received: {0}", receiveString);
    messageReceived = true;
}
public void ReceiveMessages()
{
    Console.WriteLine("listening for messages");
    while(!done){
        try
        {
            messageReceived = false;
            if (!messageReceived)
            {
                listener.BeginReceive(new AsyncCallback(ReceiveCallback),  null);
            }
            while (!messageReceived)
            {
            }

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
    Console.WriteLine("Done receiving messages...");
    for (int i = 0; i < adresses.Length; i++)
    {
        if (adresses[i] != null)
        {
            Console.WriteLine(adresses[i]);
        }
    }
    Console.ReadLine();
    listener.Close();
}'

第二

bool messageReceived = false;
bool done = false;
const int listenPort = 11000;
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,  ProtocolType.Udp);
IPEndPoint receiveEP = new IPEndPoint(IPAddress.Any, listenPort);
string[] adresses = new string[2];
byte[] buffer = new byte[1024];
public void ReceiveMessages()
{
    listener.Bind(receiveEP);
    Console.WriteLine("listening for messages");
    while (!done)
    {
        try
        {
            messageReceived = false;
            if (!messageReceived)
            {
                listener.BeginReceive(buffer, 0,1024,SocketFlags.None,new AsyncCallback(ReceiveCallback), null);
            }
            while (!messageReceived)
            {
            }

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
    Console.WriteLine("Done receiving messages...");
    for (int i = 0; i < adresses.Length; i++)
    {
        if (adresses[i] != null)
        {
            Console.WriteLine(adresses[i]);
        }
    }
    Console.ReadLine();
    listener.Close();
}
public void ReceiveCallback(IAsyncResult ar)
{
    int id = 0;
    int read = listener.EndReceive(ar);
    for (int i = 0; i < adresses.Length; i++)
    {
        if (adresses[i] == receiveEP.Address.ToString())
        {
            id = i;
            break;
        }
        else if (adresses[i] == null)
        {
            id = i;
            adresses[i] = receiveEP.Address.ToString();
            break;
        }
    }
    Console.WriteLine("Received message from {0} (client {1}):", adresses[id], id);
    string receiveString = Encoding.ASCII.GetString(buffer,0,read);
    if (receiveString == "stop")
    {
        done = true;
    }
    Console.WriteLine("Received: {0}", receiveString);
    messageReceived = true;
}'

我已经尝试过Socket.ReceiveMessageFrom()并使用它返回的packetinfo,但即使我从另一台机器发送,我也最终得到了服务器的ip4。有人可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

即使这不应该是Q / A类型的问题,我已经找到了一种让它工作的方法,这意味着receive()通过使用仅将groupEP更改为数据包发送方的IP一个Socket而不是一个UdpClient(我模仿了UdpClient的工作方式)。目前,它仍然是同步的(listener.Receive()是一个阻塞调用),但在不久的将来会改变:

def increment_invoice_number():
    last_invoice = Invoice.objects.all().order_by('id').last()
    if not last_invoice:
        return 'MAG0001'
    invoice_no = last_invoice.invoice_no
    new_invoice_no = str(int(invoice_no[4:]) + 1)
    new_invoice_no = invoice_no[0:-(len(new_invoice_no))] + new_invoice_no
    return new_invoice_no