赞
踩
最近遇到一个JAVA UDP通信的问题,说起来很简单,但是相信肯定还有和我一样踩坑的,这里记录以下。
client主动上传数据包后,server保存client的ip与端口,等到server需要主动读取时,通过保存的ip/port给client发送读取命令,client收到后响应server。
server 接收client上传的数据没问题,溜的一批。但下发读取消息时,客户端一直收不到消息。
为描述问题,献上逻辑代码,意思意思(我这边只负责服务端,客户端是嵌入式程序,我不懂…)
/*
* 接收客户端发送的数据
*/
// 1.创建服务器端DatagramSocket,指定端口
DatagramSocket socket = new DatagramSocket(8800);
// 2.创建数据报,用于接收客户端发送的数据
byte[] data = new byte[1024];// 创建字节数组,指定接收的数据包的大小
DatagramPacket packet = new DatagramPacket(data, data.length);
// 3.接收客户端发送的数据
System.out.println("****服务器端已经启动,等待客户端发送数据");
socket.receive(packet);// 此方法在接收到数据报之前会一直阻塞
DatagramSocket s = new DatagramSocket();
DatagramPacket dp = new DatagramPacket(data, data.length,
InetAddress.getByName(remoteIp), remotePort);
s.send(dp);
在本地测试环境下(server、client模拟程序都在同一局域网内),这其实也没得问题,收发都成功了。但是!!!!!server一部署到公司测试服务器上就不得行了,client收不到消息。
不饶弯子,直接说解决方法,问题出在send上,不应该new一个DatagramSocket(),应该直接使用recv时用的DatagramSocket,你品,你细品。
如果没用什么netty这样的框架,抛开业务代码,纯纯的DatagramSocket收发就这么几行代码,鬼知道我查了多少遍…直到我看到这篇文章。
简单的说,如果通信双方所处同一网络内,网络环境很直白,很纯。那么上面那么写呢是可以正常通信的。
但是!!!如果像我遇到的情况就另说了。首先,公司网络是做了NAPT的,各种内网外映射;其次客户端那边我不懂啊(我菜),什么移动基站动态分配IP端口,4G通信…我是个大白啊!!!
这种情况下,服务端想要给之前通信过的客户端发消息,需要通过Session,才能找的回去,所以如果new一个DatagramSocket,辣估计就走丢了。
这里额外提一嘴,考虑到性能问题,我用了smart-socket(为什么不用netty呢…一方面是I/O模式来说,smart-socket号称是AIO的,想比netty的NIO要快;另一方面,当然是smart-socket简单啊,几行代码就得嘞。);再实现Protocol和MessageProcessor接口时都有个参数AioSession,对,没错,就是这玩意,各单位请注意,回发时请用这个回发,别重新开个session,发不回去的。。。。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。