2016-05-16 88 views
1

我只是在學習如何編程網絡。我試圖做一個udp系統使用套接字而不是udpclient類(通過搜索我找不到很多信息)。UDP receivefrom或sendto不工作

服務器接收來自客戶端的消息並打印它們,但客戶端卡在receivefrom它阻塞該線程的地方。 我在這裏做錯了什麼?

我的服務器代碼:

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

IPEndPoint _IPEndPoint = new IPEndPoint(IPAddress.Any, 55566); 
EndPoint _EndPoint = _IPEndPoint; 
sck.Bind(_IPEndPoint); 

byte[] buffer = new byte[ 255 ]; 
int rec = sck.ReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref _EndPoint); 
Array.Resize(ref buffer, rec); 
string clientIP = Encoding.Default.GetString(buffer); 
Console.WriteLine("Received: {0}", clientIP); 

buffer = new byte[ 255 ]; 
rec = sck.ReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref _EndPoint); 
Array.Resize(ref buffer, rec); 
int clientPort = BitConverter.ToInt32(buffer, 0); 
Console.WriteLine("Received: {0}", clientPort); 

buffer = Encoding.Default.GetBytes("Hello " + clientIP); 
sck.SendTo(buffer, 0, buffer.Length, SocketFlags.None, new IPEndPoint(IPAddress.Parse(clientIP), clientPort)); // never gets received 

sck.Close(); 


Process.GetCurrentProcess().WaitForExit(); 

和客戶端代碼:

Socket sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 55566); 
sck.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 0)); 
EndPoint endPoint = ipEndPoint; 

string msg = new Func<string>(() => 
{ 
    var host = Dns.GetHostEntry(Dns.GetHostName()); 
    foreach (var ip in host.AddressList) 
    { 
     if (ip.AddressFamily == AddressFamily.InterNetwork) 
     { 
      return ip.ToString(); 
     } 
    } 
    throw new Exception("Local IP Address Not Found!"); 
})(); 
byte[] msgBuffer = Encoding.Default.GetBytes(msg); 
Console.WriteLine("sending IP"); 
sck.SendTo(msgBuffer, 0, msgBuffer.Length, SocketFlags.None, ipEndPoint); 

msgBuffer = BitConverter.GetBytes(((IPEndPoint) sck.LocalEndPoint).Port); 
Console.WriteLine("sending port"); 
sck.SendTo(msgBuffer, 0, msgBuffer.Length, SocketFlags.None, ipEndPoint); 

byte[] buffer = new byte[ 255 ]; 
Console.WriteLine("receiving message"); 
int rec = sck.ReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref endPoint); // gets stuck here 

Array.Resize(ref buffer, rec); 

Console.WriteLine("Received: " + Encoding.Default.GetString(buffer)); 

sck.Close(); 

回答

0

這是不可能肯定地說沒有更多地瞭解在你正在測試的環境。但最有可能的是,客戶端發送錯誤的IP地址和/或端口。

無論如何,服務器不應該依賴客戶端自己來報告它的地址。服務器將知道來自ReceiveFrom()方法的信息,並應該只有使用該方法發送的數據。

例如:

EndPoint clientEndPoint = new IPEndPoint(IPAddress.Any, 0); 

rec = sck.ReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref clientEndPoint); 
Array.Resize(ref buffer, rec); 
int clientPort = BitConverter.ToInt32(buffer, 0); 
Console.WriteLine("Received: {0}", clientPort); 

buffer = Encoding.Default.GetBytes("Hello " + clientIP); 
sck.SendTo(buffer, 0, buffer.Length, SocketFlags.None, clientEndPoint); // never gets received 

當然,記住,UDP是不可靠的。當使用UDP時,以下所有情況均爲真:

  1. 任何給定的數據報可能永遠不會到達。
  2. 任何給定的數據報可能會被多次接收。
  3. 發送的數據報可能以任何順序到達,無論它們的發送順序如何。

當然,這些特性可能會破壞您所寫的代碼,代碼假定數據將按某種特定順序發送和接收,而不會進行任何重新排列或重複。