我正在学习如何编程网络。我正在尝试使用套接字而不是udpclient类创建一个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();
答案 0 :(得分: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时,以下所有内容均为真:
当然,这些特征可能会对您编写的代码造成严重破坏,代码假定数据将以某种特定顺序发送和接收,而无需重新排列或重复。