1. 程式人生 > >JAVA學習線路:day14-網路程式設計

JAVA學習線路:day14-網路程式設計

>**心得:** > 我是一名正在自學的java的即將畢業的大學生 > 總結筆記是為了讓自己更好的理解和加深印象。可能不是那麼美觀,自己可以看懂就好 > *所有的文件和原始碼都開源在**GitHub**: [**https://github.com/kun213/JavaNotes**](https://github.com/kun213/JavaNotes/)上了*。希望我們可以一起加油,一起學習,一起交流 ## day14 【網路程式設計】 @[toc](今日學習內容-2020.10.16) ## 一、網路程式設計入門 ### 1.1 可以說出軟體的結構 **C/S結構** :全稱為Client/Server結構,是指客戶端和伺服器結構。常見程式有QQ、迅雷等軟體。 **B/S結構** :全稱為Browser/Server結構,是指瀏覽器和伺服器結構。常見瀏覽器有谷歌、火狐等。 ### 1.2 可以說出UDP和TCP協議特點 - **TCP**:傳輸控制協議 (Transmission Control Protocol)。TCP協議是**面向連線**的通訊協議,即傳輸資料之前,在傳送端和接收端建立邏輯連線,然後再傳輸資料,它提供了兩臺計算機之間可靠無差錯的資料傳輸。 - 三次握手:TCP協議中,在傳送資料的準備階段,客戶端與伺服器之間的三次互動,以保證連線的可靠。 - 第一次握手,客戶端向伺服器端發出連線請求,等待伺服器確認。 - 第二次握手,伺服器端向客戶端回送一個響應,通知客戶端收到了連線請求。 - 第三次握手,客戶端再次向伺服器端傳送確認資訊,確認連線。整個互動過程如下圖所示 ![](https://img-blog.csdnimg.cn/img_convert/6e82960b9e2824bc62c8931f70f96e27.png) 完成三次握手,連線建立後,客戶端和伺服器就可以開始進行資料傳輸了。由於這種面向連線的特性,TCP協議可以保證傳輸資料的安全,所以應用十分廣泛,例如下載檔案、瀏覽網頁等。 - **UDP**:使用者資料報協議(User Datagram Protocol)。UDP協議是一個**面向無連線**的協議。傳輸資料時,不需要建立連線,不管對方端服務是否啟動,直接將資料、資料來源和目的地都封裝在資料包中,直接傳送。每個資料包的大小限制在64k以內。它是不可靠協議,因為無連線,所以傳輸速度快,但是容易丟失資料。日常應用中,例如視訊會議、QQ聊天等。 每次傳送的資料最大為64kb。 ## 二、TCP通訊協議 ### 2.1 可以說出TCP協議下兩個常用類名稱 **在Java中,提供了兩個類用於實現TCP通訊程式:** - 客戶端:`java.net.Socket` 類表示。建立`Socket`物件,向服務端發出連線請求,服務端響應請求,兩者建立連線開始通訊。 - 服務端:`java.net.ServerSocket` 類表示。建立`ServerSocket`物件,相當於開啟一個服務,並等待客戶端的連線。 ### 2.2 如何編寫TCP協議下字串資料傳輸程式 實現TCP通訊的客戶端程式: ```java /** * 實現TCP通訊的客戶端程式 * * java.net.Socket 實現客戶端的套接字物件,連線物件 * * 需求: 客戶端程式和伺服器程式實現資料交換 * * 實現步驟: * 1: 建立Socket物件 (主動連線伺服器) * Socket(String host, int port) * * 2: OutputStream getOutputStream() * 返回套接字中的位元組輸出流 * 方法write寫入資料, 寫到伺服器 * * 3: InputStream getInputStream() * 返回套接字中的位元組輸入流 * 方法read讀取資料,讀取的是伺服器發回來的資料 * * 4: 釋放資源 */ public class TCPClient { public static void main(String[] args)throws IOException { //建立Socket物件 (主動連線伺服器) Socket socket = new Socket("127.0.0.1",9000); //OutputStream getOutputStream() OutputStream out = socket.getOutputStream(); //位元組流的方法寫資料 out.write("你好伺服器".getBytes());//沒有寫到檔案中,寫到了伺服器中 InputStream in = socket.getInputStream();//獲取位元組輸入流 byte[] bytes = new byte[1024]; int len = in.read(bytes);//客戶端輸入流,讀取到伺服器發回來的資料 System.out.println(new String(bytes,0,len)); //釋放資源 //out.close(); socket.close(); } } ``` 實現TCP通訊的伺服器程式: ```java /** * 實現TCP通訊的伺服器程式 * 192.168.27.95 * java.net.ServerSocket 實現TCP協議中的伺服器套接字物件 * * 實現TCP伺服器程式步驟: * 1: 建立ServerSocket物件 * ServerSocket(int port) 埠號 * * 2: 等待客戶端的連線,如果沒有客戶端連線,永遠等待 * ServerSocket類方法 accept()同意 * 方法 accept()返回值是 Socket物件 (客戶端的連線物件,包含客戶端的IP) * * 3: Socket物件中獲取到位元組輸出流 * OutputStream getOutputStream() * 方法write寫資料,寫到客戶端 * * 4: Socket物件中獲取到位元組輸入流 * InputStream getInputStream() * 方法read讀取資料,讀取的是客戶端發來資料 * * 5: 釋放資源 */ public class TCPServer { public static void main(String[] args)throws IOException { //建立ServerSocket物件 ServerSocket server = new ServerSocket(9000); //ServerSocket類方法 accept()同意 Socket socket = server.accept(); //System.out.println(socket); //使用客戶端連接獲取物件,輸入流 InputStream in = socket.getInputStream(); //in輸入流的方法read()讀取客戶端發來資料 byte[] bytes = new byte[1024]; //len返回的是讀取到的位元組個數 int len = in.read(bytes); System.out.println(new String(bytes,0,len)); //Socket客戶端物件,獲取位元組輸出流 OutputStream out = socket.getOutputStream(); out.write("收到!".getBytes());//伺服器輸出流,寫回客戶端 //釋放資源 socket.close(); server.close(); } } ``` ### 2.3 理解TCP協議下檔案上傳案例 ![](https://img-blog.csdnimg.cn/img_convert/baf7cd559981cfdca3bcfca342ac4c46.png) 實現圖片上傳客戶端: ```java /** * 實現TCP圖片上傳客戶端 * 實現步驟: * 1: 建立Socket物件,連線伺服器 * 2: FileInputStream讀取 mm.jpg 位元組陣列 * 3: Socket物件獲取位元組輸出流 * 位元組陣列,交給輸出流,寫到伺服器 * 4: Socket物件獲取位元組輸入流 * 全部的圖片傳送完畢 * 輸入流,讀取伺服器回來的提示資訊 "上傳成功" * * 客戶端方法Socket: shutdownOutput() 終止連線物件的輸出流 , * 同時跟上TCP終止序列 * 5: 釋放資源 */ public class TCPClient { public static void main(String[] args) throws IOException{ //1: 建立Socket物件,連線伺服器 Socket socket = new Socket("127.0.0.1",9000); //2: 自己的位元組輸入流,讀取圖片mm.jpg FileInputStream fis = new FileInputStream("e:/msh.jpg"); //3: Socket物件獲取位元組輸出流 OutputStream out = socket.getOutputStream();//任何資料,寫向伺服器 byte[] bytes = new byte[1024]; int len = 0; //fis讀取檔案末尾,JVM返回read() -1 while ((len = fis.read(bytes))!=-1){ out.write(bytes,0,len); } //告訴伺服器,沒資料了,別讀,伺服器傳送TCP的終止符 socket.shutdownOutput(); //4:Socket物件獲取位元組輸入流 InputStream in = socket.getInputStream();//輸入流,讀取伺服器回來的資料 len = in.read(bytes); System.out.println("伺服器提示::"+new String(bytes,0,len)); socket.close(); } } ``` 實現圖片上傳伺服器端: ```java /** * 實現圖片上傳伺服器端 * 實現步驟: * 1: 建立物件ServerSocket 繫結埠 * 2: Socket accept()方法等待客戶端連線 * 3: Socket物件,獲取位元組輸入流,讀取客戶端發來圖片的位元組 * 4: 建立位元組輸出流,讀取到圖片,寫到 e:/upload * 5: Socket物件,獲取位元組輸出流,"上傳成功"寫回客戶端 * * bug: * 1: 演示了2次,為什麼資料夾中只有一個檔案,同名覆蓋 * a: 1.jpg * b: 1.jpg * * 2: 客戶端收不到伺服器的上傳成功 //告訴伺服器,沒資料了,別讀,伺服器傳送TCP的終止符 */ public class TCPServer { public static void main(String[] args) throws IOException{ //1: 建立物件ServerSocket 繫結埠 ServerSocket server = new ServerSocket(9000); // 2: Socket accept()方法等待客戶端連線 Socket socket = server.accept(); //3: Socket物件,獲取位元組輸入流,讀取客戶端發來圖片的位元組 InputStream in = socket.getInputStream(); //4: 建立位元組輸出流,讀取到圖片,寫到 e:/upload //上傳的檔案,重新命名,獲取當前日期 轉換成字串 String filename = new SimpleDateFormat("yyyyMMddHHmmssssss").format(Calendar.getInstance().getTime())+".jpg"; FileOutputStream fos = new FileOutputStream("e:/upload/"+filename); byte[] bytes = new byte[1024]; int len = 0; //read()讀取是客戶端寫來的圖片!! while ( (len = in.read(bytes))!=-1){ fos.write(bytes,0,len); } //5: Socket物件,獲取位元組輸出流,"上傳成功"寫回客戶端 OutputStream out= socket.getOutputStream(); out.write("上傳成功!".getBytes()); socket.close(); server.close(); } } ``` ------ ***這是我的公眾號,希望大家可以關注,讓我們一起做最好的自我。 我也會把我自學視訊分享在上面,供大家一起學習。*** ![CodeBull](https://img-blog.csdnimg.cn/20201008185633816.jpg#pic_center)