在csdn上, 有人问了一个这个问题, 下面有为大神是这么回复的, 便于理解udp:
发送端口不需要固定什么4000,随机由UdpClient 选择一个发送端口就行。发送之后,立刻读取数据。而服务器端从端口8000接收到请求,应该立刻向客户端(接收消息时就会获得RemoteIpEndPoint客户端对外端口)发送返回(比如说200毫秒以内),这样就能让发送消息的客户端收到返回结果。
要注意的是,Udp通讯时你必须较快地让服务器发送返回消息,否则中间的路由器可能已经中断了处理、不再允许外部主动联系内部了。
这里有必要纠正几个很容易误导人的概念:
1. 客户端不需要固定端口,客户端发送消息时应该由UdpClient自动选择可用的端口。
2. 不要说什么“服务器向4000端口发送消息”,那是瞎扯,是因为只在小办公室里几台电脑规模的小网络下搞测试造成的。真正应用网络环境下,大部分客户端都在NAT路由器以后,就算是客户端绑定了4000固定端口,经过1个或者多个NAT路由器处理,那么服务器端针对的客户端端口也不大可能是4000,此时服务器端可能应该向“最终路由器IP、端口号62102”发送返回消息,才能到达内部局域网IP、4000号端口这里来。
3. 服务器不可能向NAT内部的客户端主动发起消息,必须等客户端发送消息,然后赶紧发送返回值。因为NAT路由器只会为Udp消息的这种回发规则维护一个较短时间,在这个较短时间上由外部发来的消息才能被路由器正确转发给内部。
比如说,你的客户端IP是192.168.0.100,端口号是4000,使用Udp方式向服务器 202.100.200.123:8000 发送了一个消息,那么经过路由器——不管中间有几个路由器——最终是以 211.149.101.21:62018 发送出去的,那么这时候难道有人告诉你说“你的服务器要向 192.168.0.100:4000 发送 Udp 返回值啊!”么?这就是误导你了。
最起码的Udp服务器端编程,也是向你的服务器端 Receive 语句所返回的 RemoteIpEndPoint(也就是211.149.101.21:62018 ) 发送返回值,这样才能最终到达局域网内 192.168.0.100:4000。而这个 RemoteIpEndPoint 的值每一次可能都是变动的,因为路由器会采用不同的端口发送不同的消息。
然后,对于客户端,你根本没有必要绑定 4000端口。你的 new UdpClient() 得到的这个对象,可以发送消息,紧接着Receive,就能收到返回值。发送端口号(不管是4000还是40000)应该由人家自动选择,你只定一个端口号没有多少好处。
当然这里是指一般的Udp通讯的概念。如果你有什么特别的“设计”,或许你确实需要固定内部端口号。但是那也是在你确实知道基本的概念之后的事情。
阅读(2922) | 评论(0) | 转发(0) |