我們知道,在上一章末我們提到了,目的主機是不能在局域網內的,那麼如何讓兩個處於不同局域網之間的主機通信呢?
我們假設兩臺主機:
主機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的私網地址是一致的,路由器找到了本機,等於自己和自己建立了通訊。(也就是說,兩個私網地址不一致,肯定接收不到)
(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只是能實現簡單的通訊嗎?我們想想服務器是什麼?我們如何把自己的電腦變成服務器?