可以建立一个Udp Server,接收发往本机所有端口的数据包吗?
可以建立一个Udp Server,接收发往本机所有端口的数据包吗?
答案:看起来不能,不知有没有什么办法。
问题提出:
下面是向本机上的Udp Server发送数据,然后再接收数据的Udp Client程序:
Socket sender=new Socket(AddressFamily.InterNetwork,
SocketType.Dgram,
ProtocolType.Udp);
EndPoint remoteEp=new IPEndPoint(IPAddress.Loopback,8004);
byte[] buf=Encoding.ASCII.GetBytes("hello");
sender.SendTo(buf,SocketFlags.None,remoteEp);//(1)
int i=sender.ReceiveFrom(buf,SocketFlags.None,ref remoteEp);
Console.WriteLine("receive from {0}",remoteEp);
string str=Encoding.ASCII.GetString(buf,0,i);
Console.WriteLine("message: {0}",str);
如果本机上的Udp Server在8004端口监听,并返回数据,那么此Client程序就能够收到数据。我就想,如果去掉(1)处的语句,然后把remoteEp改为(IPAddress.Any,0),那么不就很像一个能接收发往本机所有端口数据的Udp Server程序吗;如果remoteEp改为某个特定的IP地址,那么是否就能够接收从这台机器发来的数据包呢?
试验证明上面两个想法都是错的。在上面的Udp Client程序中,如果本机上没有一个Udp Server在8004端口监听,那么下面的ReceiveFrom函数不是漫长等待的问题,而是会抛出异常。这里,remoteEp就像是一个文件句柄,如果只是自己指定IP地址和端口,而还没有与服务器程序交流过,那么就是一个没有激活的文件句柄(自己指定句柄的值,而不是通过CreateFile或OpenFile得到的句柄),不能调用ReceiveFrom来接收数据。
得出结论就是,如果Udp Socket想调用ReceiveFrom,那么或者它是一个调用了Bind()函数的Server Socket, 或者接收函数ReceiveFrom参数中的远端EndPoint是活动的。
(总之还是不太了解,因Udp发送数据包不一定到达了目的地址,即使到了目的地址后,发送端也还是不知道是否到达了,那么在上面的Udp Client程序中(1)位置处,带有这么多不确定性地发送了一个包,为什么就使后面的ReceiveFrom能够调用成功,不然就会异常呢??)
附Udp Server程序
Socket receiver=new Socket(AddressFamily.InterNetwork,
SocketType.Dgram,
ProtocolType.Udp);
EndPoint remoteEp=new IPEndPoint(IPAddress.Any,0);
EndPoint localEp=new IPEndPoint(IPAddress.Any,8004);
receiver.Bind(localEp);
byte[] buf=new byte[256];
int i=receiver.ReceiveFrom(buf,SocketFlags.None,ref remoteEp);
Console.WriteLine("receive from {0}",remoteEp);
Console.WriteLine("message: {0}",Encoding.ASCII.GetString(buf,0,i));
receiver.SendTo(buf,0,i,SocketFlags.None,remoteEp);: