java - UDP 为每个新连接分配一个新套接字
问题描述
这是我的设置:在我的家庭网络上,服务器正在端口上运行SERVER_PORT
。已将端口转发规则添加到路由器,以便所有传入连接都SERVER_PORT
将到达服务器的机器。互联网上的其他地方存在一个客户端,它试图向服务器发送一个 UDP 数据包并接收一个返回的数据包。
服务器将接收连接,SERVER_PORT
但将从绑定到不同(随机)端口的套接字发回数据包。
这个想法是模拟一个侦听器套接字,就像用于 TCP 的套接字一样,并且为每个新连接分配一个新套接字。
我已经使用连接到我的家庭网络和家庭网络(蜂窝)之外的客户端测试了我的程序。该程序以任何方式都不起作用。
如果我使用服务器的原始套接字(绑定到的那个)发回一个数据包,该程序确实可以工作SERVER_PORT
。
我假设这与我的路由器的 NAT 表有关,但我不太清楚细节。
我的问题是如何从不同的套接字发回一个数据包,而不是用于以前的数据包的那个,如果服务器直接连接到互联网,我会遇到同样的问题吗?
我写了一个小java程序来演示这个问题:
这是服务器的代码:
//create both sockets and a buffer
DatagramSocket serverSocket1 = new DatagramSocket(SERVER_PORT);
DatagramSocket serverSocket2 = new DatagramSocket();
byte[] buffer = new byte[512];
//receive a packet from serverSocket1
DatagramPacket packet1 = new DatagramPacket(buffer, buffer.length);
serverSocket1.receive(packet1);
System.out.println("received packet from: address = " + packet1.getAddress() + ", port = "+ packet1.getPort());
//send a packet from serverSocket2
DatagramPacket packet2 = new DatagramPacket(buffer, buffer.length, packet1.getAddress(), packet1.getPort());
serverSocket2.send(packet2);
System.out.println("sent packet back");
这是客户的代码:(注意:SERVER_ADDRESS
设置为我的公共 ip)
//create a socket for the client and a buffer
DatagramSocket clientSocket = new DatagramSocket();
byte[] buffer = new byte[512];
//send packet1
DatagramPacket clientPacket1 = new DatagramPacket(buffer, 0, buffer.length, InetAddress.getByName(Server.SERVER_ADDRESS), Server.SERVER_PORT);
clientSocket.send(clientPacket1);
System.out.println("sent packet");
//receive packet2
DatagramPacket clientPacket2 = new DatagramPacket(buffer, buffer.length);
clientSocket.receive(clientPacket2);
System.out.println("received packet from: address = " + clientPacket2.getAddress() + ", port = "+ clientPacket2.getPort());
在首先运行服务器和客户端后,我得到以下输出:
服务器:
received packet from: address = /107.107.56.147, port = 29098
sent packet back
客户:
sent packet
解决方案
推荐阅读
- c# - 如何使用数据类型 List 初始化新对象
? - python - ValueError: int() 以 10 为基数的无效文字:''(可能是文件处理不当)
- javascript - 按文件类型进行元素预览,例如 [img,video,audio]
- laravel - 如何在 api 控制器中检查当前登录用户的 laravel spatie 权限?
- ruby-on-rails - 使用 chrome 自动完成时,ruby on rails 应用程序出现故障
- android - BoundService 中的 AltBeacon 库扫描不会在 unbind() 上停止 - Android O
- python - 根据行值使用其他列的名称填充新的 pandas 数据框列
- javascript - 当我调整浏览器窗口的大小时,我的图像会在它们应该保持在一起时移动
- bash - /bin/sh -l -c 'command' 不加载配置文件
- java - 默认方法中的这个关键字