UDP receivefrom或sendto不工作
问题描述:
我只是在学习如何编程网络。我试图做一个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();
答
这是不可能肯定地说没有更多地了解在你正在测试的环境。但最有可能的是,客户端发送错误的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时,以下所有情况均为真:
- 任何给定的数据报可能永远不会到达。
- 任何给定的数据报可能会被多次接收。
- 发送的数据报可能以任何顺序到达,无论它们的发送顺序如何。
当然,这些特性可能会破坏您所写的代码,代码假定数据将按某种特定顺序发送和接收,而不会进行任何重新排列或重复。