Java - Destination unreachable (Port unreachable) UDPServer 响应response,无法发送出去
我们直接看这个抓包文件截图,xxx.6(src) -> xxx.8(nginx) -> xxx.194(udpserver) -> xxx.8(nginx) ... ... over
xxx.6(src):是我本地模拟器的IP;
xxx.8(nginx):是项目网关服务器,装有NGINX,负责数据转发;
xxx.194(udpserver):是项目服务器,负责项目数据处理;
Server是UDPServer,在做数据的响应的时候,发现模拟器总是收不到数据,然而从日志看,数据已经发送出去了,而且UDP是无状态的,只好通过抓包来看看数据在哪里出问题了;
我的代码部分是这样做的:
DatagramSocket server = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, port);
server.send(packet);
server.close();
会随机绑定一个端口,例如截图中的端口号52839,发送数据到Nginx,正常Nginx会将我这个数据转发到,原来数据进来的port才对,但是如图报了一个端口未监听的错;
排查Nginx的配置:
upstream xxx {
server xxx.xx.xx.194:9080;
}
server {
listen 9080 udp;
proxy_pass xxx ;
proxy_responses 10;
proxy_timeout 1s;
proxy_connect_timeout 1s;
proxy_bind $remote_addr transparent;
}
但是仍然不起作用,只好回到代码部分看看,尝试直接在数据上来的同时直接回复数据,代码:
// 侦听本机port端口的udp数据包
server = new DatagramSocket(9080);
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
server.receive(packet);
byte[] bufs = ackpayload.getBytes();
DatagramPacket sendPacket = new DatagramPacket(bufs, bufs.length, packet.getAddress(), packet.getPort());
// 发送消息
server.send(sendPacket);
抓包可以看到:
发现是可以发送出去的,模拟器也可以迅速的接收到数据,但是发送的时候绑定的端口,竟然是udpserver的监听端口,很有意思啊。。。我认为是因为要维持网络层面的数据通信,必须在回复数据的时候,也按照原来的通道回去,否则网络层面是无法将一个新的response关联到原来的数据通道上的;
故,代码部分做了一个改动,由原来最简单的socket改为netty来封装接收数据;