我们知道,在上一章末我们提到了,目的主机是不能在局域网内的,那么如何让两个处于不同局域网之间的主机通信呢?
(我真是服了,老自动设置vip干啥,还要重新发布)
我们假设两台主机:
主机A:192.168.1.105
主机B:192.168.1.105
(如果对这两个IP地址为什么一样的话,建议先读读前篇文章)
我们思考一下原因,由于当两方都处在各自局域网的时候,拥有的都是私网IP地址,我们让A去联系主机B,A的路由器根据B的私网IP地址(192.168.1.105)去寻址的话,哎呦,还找到了主机,进行一下通讯,还成功了? 这里给个TCP程序:(实现A给B发送一个字符串,在B上显示,我们使用的是TCP连接,UDP也行)
(1)输入B的私网地址通讯
import java.io.*; //服务器端,我们假设这是B
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
private static final int PORT = 9999;
public static void main(String[] args) throws IOException {
// 启动TCP服务器
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("服务器已启动");
// 循环获取新的客户端连接
while (true){
// 阻塞,等待新的客户端连接
Socket socket = serverSocket.accept();
// 处理这个客户端连接的业务,这个业务可能会发生阻塞
//先不考虑阻塞的实现
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is,"UTF-8"));
OutputStream os = socket.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os,"UTF-8"));
// 1.先接收客户端数据,再打印
String line;
while((line = br.readLine()) != null){
System.out.println("服务端接收到数据:"+line);
// 2.响应给客户端数据,我已经接收到xxx消息
bw.write("我已经接收到了"+line+"消息\n");
bw.flush();
}
}
}
}
import java.io.*;
import java.net.Socket; //假设这是A
public class TCPClient {
private static final String HOST = "192.168.1.105";
// 本机默认的域名localhost,默认ip是127.0.0.1
private static int PORT = 9999;
public static void main(String[] args) throws IOException {
// 建立客户端到服务器的连接
Socket socket = new Socket(HOST,PORT);
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is,"UTF-8"));
OutputStream os = socket.getOutputStream();
PrintStream pw = new PrintStream(os,true);
pw.println("Hello,B");
}
}
我们先启动B,然后启动A,我们一看,B显示出来了“Hello,B”,这不是找到了吗???
其实本应该是找不到的,但因为A和B的私网地址是一致的,路由器找到了本机,等于自己和自己建立了通讯。(也就是说,输入的服务端IP一定是局域网存在的,且开辟了相应的端口,且能建立Socket通讯,然后才能通信。这些条件缺一不可)
(2)输入B的公网地址
B一查自己,公网IP:117.36.200.116(百度直接输入“IP”可以看自己的公网IP)
然后我们把A端的程序IP地址HOST一改
private static final String HOST = "117.36.200.116";
最终发现也不行,我们知道由于NAT+NAPT的原因,我们的数据包IP地址是要转变成公网IP的,端口也会映射新端口,那么这是路由器被动的过程,也就是说A发送了数据包后,A的路由就可以找到A主机了,但是B没有发送数据包,B的路由器找不到B,输入了公网IP,也只是找到了B的路由器所在,找不到具体主机和端口。
那么,我们如何实现两台局域网主机之间通讯?
也有方法,我们说一下内网穿透。
内网穿透: 即NAT穿透,网络连接时术语,计算机是局域网内时,外网与内网的计算机节点需要连接通信,有时就会出现不支持内网穿透。就是说映射端口,能让外网的电脑找到处于内网的电脑,提高下载速度。
我们只需要先进行映射,把自己的私网IP映射成指定的公网IP地址,把原本的端口号映射成指定的端口。
这里推荐一款软件:[花生壳](https://hsk.oray.com/)
使用这款软件,就可以让B变成公网IP,把B的公网IP输入,再输入映射后的端口就可以收到了信息了。
【思考】: 当B的私有IP变成公有IP只是能实现简单的通讯吗?我们想想服务器是什么?我们如何把自己的电脑变成服务器?