2015-12-24 29 views
2

我目前工作的一個簡單的UDP客戶端/服務器系統上的客戶端的IP,我偶然發現了以下內容:當我嘗試在獲得IPEndPoint的IP(這我拿來使用IPAdress.Any)使用UdpClient它的工作原理,我得到以下結果(前一)程序:獲取使用IPAddress.Any

image

但是當我用普通插座代替UdpClient的它在某種程度上無法區分客戶端/ IPS(下一個) 。下面列出了兩者的代碼。我想使用套接字的原因是因爲使用相同的類來發送和接收(不是同一個實例)是方便的,並且使代碼更容易理解。

首先

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

即使這是永遠應該是一個Q/A類型的問題,我發現得到它的工作,這意味着接收()僅通過改變groupEP到數據包的發送者的IP的方式使用Socket而不是UdpClient(我模仿UdpClient的工作方式)。目前,它仍然是同步的(listener.Receive()是阻止呼叫),但在不久的將來會改變:

private const int listenPort = 11000; 
    public static int Main() 
    { 
     bool done = false; 
     Listener listener = new Listener(listenPort); 
     IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort); 
     byte[] buffer = new byte[2048]; 
     string received_data; 
     try 
     { 
      while (!done) 
      { 
       Console.WriteLine("Waiting for broadcast"); 
       buffer=listener.Receive(ref groupEP); 
       received_data = Encoding.ASCII.GetString(buffer); 
       Console.WriteLine("Received a broadcast from {0}: {1}", groupEP.ToString(), received_data); 
      } 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.ToString()); 
     } 
     return 0; 
    } 
} 
public class Listener 
{ 
    public Socket client; 
    public AddressFamily adressFamily; 
    byte[] byte_buffer = new byte[2048]; 
    public int port; 
    public Listener(int p) 
    { 
     port=p; 
     adressFamily = AddressFamily.InterNetwork; 
     IPEndPoint localEP; 
     localEP = new IPEndPoint(IPAddress.Any, port); 
     client = new Socket(this.adressFamily, SocketType.Dgram, ProtocolType.Udp); 
     client.Bind(localEP); 
    } 
    public byte[] Receive(ref IPEndPoint remoteEP) 
    { 
     IPEndPoint ipEndPoint=new IPEndPoint(IPAddress.Any,port); 
     EndPoint endPoint = (EndPoint)ipEndPoint; 

     int num = client.ReceiveFrom(byte_buffer, 2048, SocketFlags.None, ref endPoint); 
     remoteEP = (IPEndPoint)endPoint; 
     if (num < 2048) 
     { 
      byte[] array = new byte[num]; 
      Buffer.BlockCopy(byte_buffer, 0, array, 0, num); 
      return array; 
     } 
     return byte_buffer; 
    }