UDP receivefrom 或 sendto 不工作
UDP receivefrom or sendto not working
我正在学习如何对网络进行编程。我正在尝试使用套接字而不是 udpclient class 创建一个 udp 系统(我通过搜索找不到太多信息)。
服务器从客户端接收消息并打印它们,但客户端卡在 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 地址 and/or 端口。
无论如何,服务器都不应该依赖客户端本身来报告其地址。服务器将知道来自 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 时,以下所有情况均成立:
- 任何给定的数据报可能永远不会到达。
- 任何给定的数据报都可能被多次接收。
- 发送的数据报可能以任何顺序到达,无论它们的发送顺序如何。
自然地,这些特征可能会对您编写的代码造成严重破坏,其中代码假定数据将以某种特定顺序发送和接收,并且没有任何重新排列或重复。
我正在学习如何对网络进行编程。我正在尝试使用套接字而不是 udpclient class 创建一个 udp 系统(我通过搜索找不到太多信息)。
服务器从客户端接收消息并打印它们,但客户端卡在 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 地址 and/or 端口。
无论如何,服务器都不应该依赖客户端本身来报告其地址。服务器将知道来自 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 时,以下所有情况均成立:
- 任何给定的数据报可能永远不会到达。
- 任何给定的数据报都可能被多次接收。
- 发送的数据报可能以任何顺序到达,无论它们的发送顺序如何。
自然地,这些特征可能会对您编写的代码造成严重破坏,其中代码假定数据将以某种特定顺序发送和接收,并且没有任何重新排列或重复。