如果我事先知道两台不同局域网的主机的映射IP地址和映射端口号,并且双方都通过某种网络通讯工具(socket)向对方发送数据,使双方的路由器建立映射表,那么可以不通过公网服务器进行通讯吗?
2条回答 默认 最新
关注- 你可以看下这个问题的回答https://ask.csdn.net/questions/7769353
- 除此之外, 这篇博客: 网络编程中的 (1). 创建 Socket:根据指定服务端的 IP 地址或端口号构造Socket类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
// 向服务器(域名是host。端口号为port)发起TCP连接,若成功,则创建Socket对象,否则抛出异常。 Scocket socket = new Socket(InetAddress.getByName("LAPTOP-RSJSE505"),9999); // 根据InetAddress对象所表示的IP地址以及端口号port发起连接。 Socket socket = new Socket(InetAddress.getByName("172.17.31.57"),9999);- 以下回答由chatgpt基于相关博客总结生成:
对于两台不同局域网的主机,在没有公网服务器的情况下进行通讯并不是一件容易的事情。因为局域网和公网是隔离的,也就是说,两台主机之间是无法直接通讯的。但是,在一些特殊情况下,可以通过使用NAT(网络地址转换)来实现两台主机之间的通讯。
具体实现方法如下:
-
在两台主机上都安装一个支持UPnP协议的软件,如端口映射工具。
-
在局域网中,通过UPnP协议向路由器申请外网IP和端口的映射。
-
通过UPnP协议向路由器注册一个回调监听函数,以便在路由器映射规则发生变化时能够及时得到通知。
-
在程序中设置一个监听端口并绑定到本地IP地址。
-
创建一个套接字并连接远程主机的映射IP地址和端口号。
-
发送数据。
-
接收数据。
参考代码如下:
import java.net.*; import java.io.*; public class Client { public static void main(String [] args) { String serverName = "192.168.1.100"; int port = 9999; try { // 创建一个套接字并连接远程主机的映射IP地址和端口号 Socket client = new Socket(serverName, port); System.out.println("已连接到主机: " + client.getRemoteSocketAddress()); // 发送数据 OutputStream outToServer = client.getOutputStream(); DataOutputStream out = new DataOutputStream(outToServer); out.writeUTF("Hello from " + client.getLocalSocketAddress()); // 接收数据 InputStream inFromServer = client.getInputStream(); DataInputStream in = new DataInputStream(inFromServer); System.out.println("服务器响应: " + in.readUTF()); // 关闭套接字 client.close(); } catch (IOException e) { e.printStackTrace(); } } }import java.net.*; import java.io.*; public class Server extends Thread { private ServerSocket serverSocket; public Server(int port) throws IOException { // 在程序中设置一个监听端口并绑定到本地IP地址 serverSocket = new ServerSocket(port); serverSocket.setSoTimeout(100000); } public void run() { while(true) { try { System.out.println("等待远程连接,端口号为:" + serverSocket.getLocalPort() + "..."); // 等待客户端连接 Socket server = serverSocket.accept(); System.out.println("远程主机地址:" + server.getRemoteSocketAddress()); // 接收数据 DataInputStream in = new DataInputStream(server.getInputStream()); System.out.println(in.readUTF()); // 向客户端发送响应数据 DataOutputStream out = new DataOutputStream(server.getOutputStream()); out.writeUTF("谢谢连接我:" + server.getLocalSocketAddress() + "\nGoodbye!"); // 关闭套接字 server.close(); } catch (SocketTimeoutException s) { System.out.println("Socket timed out!"); break; } catch (IOException e) { e.printStackTrace(); break; } } } public static void main(String [] args) { int port = 9999; try { // 开启服务器监听 Thread t = new Server(port); t.start(); } catch (IOException e) { e.printStackTrace(); } } }需要特别注意,因为NAT的运作机制是根据TCP/UDP数据包的头字段进行操作,所以使用非标准的TCP/UDP数据包(例如自定义TCP/UDP数据包)可能会导致NAT无法工作。此外,由于UPnP协议实现较为复杂,在使用过程中也要注意网络安全问题。
-
解决 无用评论 打赏 举报