2016-05-16 56 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. 发送的数据报可能以任何顺序到达,无论它们的发送顺序如何。

当然,这些特性可能会破坏您所写的代码,代码假定数据将按某种特定顺序发送和接收,而不会进行任何重新排列或重复。