UDP receivefrom或sendto无法正常工作

时间:2016-05-16 01:48:21

标签: c# networking udp

我正在学习如何编程网络。我正在尝试使用套接字而不是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();

1 个答案:

答案 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时,以下所有内容均为真:

  1. 任何给定的数据报可能永远不会到达。
  2. 任何给定的数据报可能会被多次收到。
  3. 发送的数据报可以按任何顺序到达,无论发送顺序如何。
  4. 当然,这些特征可能会对您编写的代码造成严重破坏,代码假定数据将以某种特定顺序发送和接收,而无需重新排列或重复。