網絡編程顧名思義就是編寫能夠進行網絡數據交互的應用程序。
網絡編程三要素
在學習網絡編程之前我們必須瞭解一些有關網絡的一些關鍵詞。
【ip地址】
ip地址用來標識網絡中的一臺主機,在同一個局域網中ip地址不能重複。
分爲ipv4和ipv6
- IpV4: 4個字節 4*8=32位
如:192.168.1.11
- IpV6: 16個字節 16*8=128位
如:fe80::2ca8:cc7e:bef0:a1cf%12
注意:如果自己的電腦沒有連接互聯網或者局域網,
可以使用127.0.0.1地址用於測試學習,這個地址可以用於本機和本機進行通訊。
【端口號】
表示一臺主機上的某一個程序,用一個整數表示
【網絡協議】
表示在網絡中數據通信的規則
UDP: 面向無連接的,不可靠的網絡協議,效率高
TCP: 面向有連接,可靠的網絡協議,效率低
InetAddress類
先學習一個表示IP地址的類InetAddress,該類中提供了一些方法用於獲取主機名或者主機地址。
public static InetAddress getByName(String host)
根據主機名或者ip地址,獲取InetAddress對象
public String getHostAddress()
獲取主機ip地址
public String getHostName()
獲取主機名稱
演示上面方法的使用
public class InetAddressDemo {
public static void main(String[] args){
//獲取InetAddress對象
InetAddress address = InetAddress.getByName("192.168.31.130");
System.out.println(address);
//獲取ip地址
String hostAddress = address.getHostAddress();
System.out.println(hostAddress);
//獲取主機名
String hostName = address.getHostName();
System.out.println(hostName);
}
}
UDP通信
UDP通信是面向無連接的數據報協議。Java支持UDP協議的網絡通信,需要使用DatagramSocket和DatagramPacket兩個類來實現。
DatagramSocket:
用於發送數據和接收數據的一個端點(類似於郵局)
DatagramPacket:
用於封裝數據的數據報(類似於快遞包裹)
封裝的數據有:
字節數組(包裹內容)
數組長度(包裹重量)
對方的ip地址(收件人郵政編碼)
對方的端口號(收件人電話號碼)
UDP發送端
public class Sender{
public static void main(String[] args){
//1)創建能發送數據的對象DatagramScoket
DatagramScoket ds=new DatagramSocket();
//2)創建數據包DategramPacket
String str="我肚子餓了,給我來一盤酸菜";
byte[] bs=str.getBytes();
DatagramPacket dp=new DatagramPacket(
bs,
bs.length,
InetAddress.getByName("127.0.0.1"),
9000);
//3)發送數據
ds.send(dp);
//4)關閉資源
ds.close();
}
}
UDP接收端
/*
注意事項:
1,發送端DatagramPacket的端口號和接收端DatagramSocket綁定的端口號必須一樣
2,端口號不能重複綁定。
*/
public class Reveiver{
public static void main(String[] args){
//1)創建能接收數據的對象DatagramScoket,綁定端口:9000
DategramScoket ds=new DategramSocket(9000);
//2)接收數據
//準備用於接收數據的數據包對象
byte[] bs=new byte[1024];
DatagramPacket dp=new DatagramPacket(bs,bs.length);
ds.receive(dp);
//3)解析數據
InetAddress address=dp.getInetAddress();// 獲取ip地址對象
byte[] data=dp.getData();// 獲取數據包中的數據
int length=dp.getLength(); //獲取有效的字節長度
int port=dp.getPort(); //獲取端口號
//4)關閉資源
ds.close();
}
}
把上面代碼寫好之後,必須先運行接收端,再運行發送端。接收端執行到receive方法時會進去阻塞狀態,等待發送端使用send方法發送數據,一旦數據發送了,接收端就會從阻塞的地方繼續執行。
TCP通信
TCP通信需要有客戶端和服務端,只有在客戶端開啓的情況下,客戶端才能連接服務端。 客戶端用Socket表示,服務端用ServerSocket表示。它們之間進行數據交互是通過流來交互的。客戶端和服務端進行數據交互都是通過IO流實現的。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Hx3brWKN-1591172328921)(assets/1585124213442.png)]
TCP客戶端
public class Client{
public static void main(String[] args){
//1) 創建連接(客戶端 去連接 服務器)
Socket socket=new Socket("127.0.0.1",8000);
//2) 獲取輸出流對象
OutputStream out=socket.getOutputStream();
//3) 往服務器寫數據
out.write("HelloWorld".getBytes());
//4) 讀取服務端發過來的數據
InputStream in=socket.getInputStream();
byte[] bytes=new byte[1024];
in.read(bytes);
//5) 關閉資源
socket.close();
}
}
TCP服務端
public class Server{
public static void main(String[] args){
//1) 創建服務端ServerSocket
ServerSocket server=new ServerSocket(8000);
//2) 監聽獲取客戶端Socket
Socket socket=server.accept();
//3) 獲取輸入流,讀取客戶端數據
InputStream in=socket.getInputStream();
byte[] bytes=new byte[1024];
in.read(bytes);
//4) 獲取輸出流對象,往客戶端寫數據
OutputStream out=socket.getOutputStream();
out.write("寫數據給客戶端".getBytes());
//4) 關閉資源
socket.close();
}
}
TCP通信必須先開啓服務端,服務端代碼執行到accpet方法時就會進入阻塞狀態,等待客戶端過來鏈接,當客戶端和服務端鏈接了鏈接,就繼續往下執行讀取客戶端發過來的數據。