Java:帶你瞭解網路程式設計
網路程式設計
1.網路程式設計概述:
計算機網路:
是指將地理位置不同的具有獨立功能的多臺計算機及其外部裝置連線起來,在網路作業系統、網路管理軟體及網路通訊協議的管理和協調下,實現資源共享和資訊傳遞的計算機系統。
網路程式設計:
就是用來實現網路互連和不同計算機上執行的程式間可以進行資料交換。
2.網路模型:
計算機網路之間以何種規則進行通訊,就是網路模型研究的問題。
網路模型一般是指:
OSI(Open System Interconnection開放系統互連)參考模型
TCP/IP參考模型
3.網路參考模型圖:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-paSxQMkC-1607421495431)(C:\Users\24582\AppData\Roaming\Typora\typora-user-images\image-20201208095857893.png)]
***1.物理層:***主要定義物理裝置標準,如網線的介面型別、光纖的介面型別、各種傳輸介質的傳輸速率等。它的主要作用是傳輸位元流(就是由1、0轉化為電流強弱來進行傳輸,到達目的地後在轉化為1、0,也就是我們常說的數模轉換與模數轉換)。這一層的資料叫做位元。
***2.資料鏈路層:***主要將從物理層接收的資料進行MAC地址(網絡卡的地址)的封裝與解封裝。常把這一層的資料叫做幀。在這一層工作的裝置是交換機,資料通過交換機來傳輸。
***3.網路層:***主要將從下層接收到的資料進行IP地址(例192.168.0.1)的封裝與解封裝。在這一層工作的裝置是路由器,常把這一層的資料叫做資料包。
***4.傳輸層:***定義了一些傳輸資料的協議和埠號(WWW埠80等),如:TCP(傳輸控制協議,傳輸效率低,可靠性強,用於傳輸可靠性要求高,資料量大的資料),UDP(使用者資料報協議,與TCP特性恰恰相反,用於傳輸可靠性要求不高,資料量小的資料,如QQ聊天資料就是通過這種方式傳輸的)。 主要是將從下層接收的資料進行分段和傳輸,到達目的地址後再進行重組。常常把這一層資料叫做段。
***5.會話層:***通過傳輸層(埠號:傳輸埠與接收埠)建立資料傳輸的通路。主要在你的系統之間發起會話或者接受會話請求(裝置之間需要互相認識可以是IP也可以是MAC或者是主機名)
***6.表示層:***主要是進行對接收的資料進行解釋、加密與解密、壓縮與解壓縮等(也就是把計算機能夠識別的東西轉換成人能夠能識別的東西(如圖片、聲音等)。
**7.應用層: **主要是一些終端的應用,比如說FTP(各種檔案下載),WEB(IE瀏覽),QQ之類的(可以把它理解成我們在電腦螢幕上可以看到的東西.就是終端應用)。
4.網路通訊三要素:
①IP地址:
InterAddress
網路中的裝置標識,不容易記憶,可用主機名
②埠號
用於標識進行的邏輯地址,不同程序進行標識
③傳輸協議
通訊的規則
常見協議:TCP/UDP
5.IP地址:
引入:
要想讓網路中的計算機能夠互相通訊,必須為每臺計算機制定一個標識號,通過這個標識號來指定要接收資料的計算機和識別傳送的計算機,在TCP/IP協議中,這個標識號就是IP地址。
那麼,我們如何獲取和操作IP地址呢?
為了方便我們對IP地址的獲取和操作,java提供了一個類InetAddress供我們使用。
舉例:
所謂IP地址就是給每個連線在Internet上的主機分配的一個32bit地址。按照TCP/IP規定,IP地址用二進位制來表示,每個IP地址長32bit,位元換算成位元組,就是4個位元組。例如一個採用二進位制形式的IP地址是“00001010000000000000000000000001”,這麼長的地址,人們處理起來也太費勁了。為了方便人們的使用,IP地址經常被寫成十進位制的形式,中間使用符號“.”分開不同的位元組。於是,上面的IP地址可以表示為“10.0.0.1”。IP地址的這種表示法叫做“點分十進位制表示法”,這顯然比1和0容易記憶得多。
組成:
IP地址 = 網路號碼+主機地址
分類:
A類 1.0.0.1—127.255.255.254
(1)10.X.X.X是私有地址(私有地址就是在網際網路上不使用,而被用在區域網絡中的地址) (2)127.X.X.X是保留地址,用做迴圈測試用的。
B類 128.0.0.1—191.255.255.254
172.16.0.0—172.31.255.255是私有地址。169.254.X.X是保留地址。
C類 192.0.0.1—223.255.255.254 192.168.X.X是私有地址,配置路由器很常見
D類 224.0.0.1—239.255.255.254
E類 240.0.0.1—247.255.255.254
特點:
A類IP地址:第一段號碼為網路號碼,剩下的三段號碼為本地計算機的號碼
B類IP地址:前二段號碼為網路號碼,剩下的二段號碼為本地計算機的號碼
C類IP地址:前三段號碼為網路號碼,剩下的一段號碼為本地計算機的號碼
特殊地址:
127.0.0.1 迴環地址,可用於測試本機的網絡卡是否有問題. ping 127.0.0.1
DOS命令 ipconfig:檢視本機IP地址
6.InetAddress類的使用:
概述:
此類表示網際網路協議 (IP) 地址。
方法:
沒有構造方法,那麼如何使用該類的功能呢?
通過靜態方法可以獲取
public static InetAddress getByName(String host)
在給定主機名的情況下確定主機的 IP 地址。
public String getHostName()
獲取此 IP 地址的主機名。
public String getHostAddress()
返回 IP 地址字串(以文字表現形式)。
程式碼:
public class IPDemo1 {
public static void main(String[] args) throws UnknownHostException {
//獲取IP地址物件
InetAddress address = InetAddress.getByName("DESKTOP-JTS3UA1");
//獲取物件幹什麼?
String hostName = address.getHostName();//獲取此IP地址的主機名
String hostAddress = address.getHostAddress();//獲取此IP地址物件的IP地址
System.out.println(hostName+"---"+hostAddress);
}
}
7.埠號:
概述:
物理埠,網絡卡口
邏輯埠,我們一般說的就是邏輯埠
A:每個網路程式至少都會有一個邏輯埠
B:用於標識程序的邏輯地址,不同程序的標識
C:有效埠:0-65535,其中0-1024系統使用或者保留埠。
8.網路協議:
UDP
將資料來源和目的封裝成資料包中,不需要建立連線,每個資料的大小控制在64k。因無連線,是不可靠協議,不需要建立連線,所以速度快。
TCP
建立連線,形成傳輸資料的通道,在連線中進行大資料量傳輸。通過三次握手完成連線,是可靠協議。必須建立連線,所以效率會稍低。
三次握手:a.我要給你傳送訊息了
b.你收到了我要給你發東西的通知,並反饋我發吧
c.我開始發了
9.Socket:
概要:
網路上具有唯一標識的IP地址和埠號組合在一起才能構成唯一能識別的識別符號套接字
Socket原理機制:
通訊的兩端都要有Socket
網路通訊其實就是Socket間的通訊
資料在兩個Socket間通過IO傳輸
圖解:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-eMHbX1Cn-1607421495433)(C:\Users\24582\AppData\Roaming\Typora\typora-user-images\image-20201208105157749.png)]
10.UDP:
使用:
1.DatagramSocket與DatagramPacket
2.建立傳送端,接收端
3.建立資料包
4.呼叫Socket的傳送接收方法
5.關閉Socket
6.傳送端和接收端是兩個獨立的執行程式
傳送端:
傳送端傳輸步驟:
1.建立UDP的Socket服務
2.將要傳送的資料封裝成資料包
3.通過UDP的Socket服務,將資料包發出
4.關閉資源
傳送端程式碼:
/**
* 1.建立UDP的Socket服務
* 2.將要傳送的資料封裝成資料包
* 3.通過UDP的Socket服務,將資料包發出
* 4.關閉資源
*
* DatagramSocket:此類表示用來發送和接收資料報包的套接字。
* public void send(DatagramPacket p):從此套接字傳送資料報包。
*
* DatagramPacket:此類表示資料報包。
* DatagramPacket(byte[] buf, int length, InetAddress address, int port)
*/
public class SendDemo {
public static void main(String[] args) throws IOException {
//1.建立UDP的Socket服務
DatagramSocket ds = new DatagramSocket();
//2.將要傳送的資料封裝成資料包
byte [] bytes ="hello,world,java".getBytes();
int length = bytes.length;
InetAddress address = InetAddress.getByName("DESKTOP-JTS3UA1");
int port = 10010;//埠
DatagramPacket dp = new DatagramPacket(bytes,length,address,port);
//3.通過UDP的Socket服務,將資料包發出
ds.send(dp);
//4.關閉資源
ds.close();
}
}
接收端:
傳輸步驟:
1.建立UDP的Socket服務。
2.通過recevice方法接收資料。
3.將收到的資料儲存到資料包物件中。
4.通過資料包物件的功能來完成對接收到資料進行解析。
5.可以對資源進行關閉。
接收端程式碼:
public class ReceviceDemo {
public static void main(String[] args) throws IOException {
//1.建立UDP的Socket服務。
DatagramSocket ds = new DatagramSocket(10010);
//2.建立資料包
byte [] bytes = new byte[1024];
int length = bytes.length;
DatagramPacket dp = new DatagramPacket(bytes,length);
//3.通過recevice方法接收資料。
ds.receive(dp);
//4.解析
byte[] data = dp.getData();
int length1 = dp.getLength();
System.out.println(new String(data,0,length1));
//
ds.close();
}
}
練習程式碼:
從鍵盤錄入資料進行傳送,如果錄入到520,那麼客戶端就結束輸入資料。
//傳送端
public class SendWork {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket();
//鍵盤錄入物件
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while ((line = br.readLine()) != null) {
if("520".equals(line)){
break;
}
byte[] bytes = line.getBytes();
DatagramPacket dp = new DatagramPacket(bytes, bytes.length,
InetAddress.getByName("DESKTOP-JTS3UA1"), 10011);
ds.send(dp);
}
ds.close();
}
}
//接收端
public class ReceviceWork {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket(10011);
while (true) {
byte[] bytes = new byte[1024 * 64];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
ds.receive(dp);
System.out.println(new String(dp.getData(), 0, dp.getLength()));
}
}
}
11.TCP:
用法:
Socket和ServerSocket
建立客戶端和伺服器端
建立連線後,通過Socket中的IO流進行資料的傳輸
關閉Socket
這裡的客戶端和伺服器端是兩個獨立的程式
客戶端:
TCP傳送端傳輸步驟:
1.建立客戶端的Socket服務,明確要連線的伺服器。
2.如果連線建立成功,就表明已經建立了資料傳輸通道,就可以在該通道通過IO流進行資料的讀取和寫入。該通道稱為Socket流,Socket流中既有讀取流,也有寫入流。
3.通過Socket物件獲取這兩個流。
4.通過流物件,可以對資料進行傳輸。
5.傳輸完畢,關閉資源。
public class SocketDemo {
public static void main(String[] args) throws IOException {
//1.建立客戶端的Socket服務
Socket s = new Socket("192.168.1.113",9999);
//2.通過Socket物件獲取這兩個流。
OutputStream os= s.getOutputStream();
os.write("hello,world,java".getBytes());
s.close();
}
}
服務類:
TCP接收端傳輸步驟:
1.建立伺服器端的Socket服務,需要一個埠
2.伺服器沒有直接流的操作,而是通過accept方法獲取客戶端物件,在通過獲取到的客戶端物件的流和客戶端進行通訊
3.通過客戶端的獲取流物件的方法,讀取資料或者寫入資料
4.如果伺服器完成,然後需要關閉客戶端,然後關閉伺服器。但是現實中一般情況向下是不會關閉伺服器的,因為要一致提供服務。
public class ServerDemo {
public static void main(String[] args) throws IOException {
//1.建立伺服器端的Socket服務,需要一個埠
ServerSocket ss = new ServerSocket(9999);
//2.通過accept方法獲取客戶端物件,在通過獲取到的客戶端物件的流和客戶端進行通訊
Socket accept = ss.accept();
//3.通過客戶端的獲取流物件的方法,讀取資料或者寫入資料
InputStream is = accept.getInputStream();
byte[] bytes = new byte[1024];
int length = is.read();
System.out.println(new String(bytes,0,length));
//4.如果伺服器完成,然後需要關閉客戶端,然後關閉伺服器。但是現實中一般情況向下是不會關閉伺服器的,因為要一致提供服務。
accept.close();
//ss.close();
}
}
思考:
客戶端連線上伺服器端,兩端都在等待,沒有任何資料傳輸。
原因:因為read方法或者readLine方法是阻塞式
解決方式:使用shutdownInput,shutdownOutput方法。