Java網絡編程詳解

內容:java

一、網絡通訊協議編程

二、UDP與TCP數組

三、UDP通訊安全

四、TCP通訊服務器

五、網絡編程總結網絡

 

 

 

一、網絡通訊協議socket

(1)基本概念學習

網絡:由多臺計算機以及外部設備鏈接起來的一個系統,咱們稱之爲網絡spa

通訊協議:就像交通規則,規定網絡上傳輸的數據的格式、大小、速度等.net

在咱們如今的網絡中都有哪些通訊協議:

  • TCP/IP
  • UDP
  • 其餘協議

 

(2)TCP/IP

網絡通訊協議有不少種,目前應用最普遍的是TCP/IP協議(Transmission Control Protocal/Internet Protocal),

它是一個包括TCP協議和IP協議,UDP(User Datagram Protocal)協議和其它一些協議的協議組,在學習具體協議

以前首先了解一下TCP/IP協議組的層次結構。

在進行數據傳輸時,要求發送的數據與收到的數據徹底同樣,這時,就須要在原有的數據上添加不少信息,以保證數據在

傳輸過程當中的數據格式徹底一致。TCP/IP協議的層次結構比較簡單,共分爲四層,如圖所示:

上圖中,TCP/IP協議中的四層分別是應用層、傳輸層、網絡層和鏈路層,每層分別負責不一樣的通訊功能,詳細解釋:

  • 鏈路層:鏈路層是用於定義物理傳輸通道,一般是對某些網絡鏈接設備的驅動協議,例如針對光纖、網線提供的驅動。
  • 網絡層:網絡層是整個TCP/IP協議的核心,它主要用於將傳輸的數據進行分組,將分組數據發送到目標計算機或者網絡。
  • 運輸層:主要使網絡程序進行通訊,在進行網絡通訊時,能夠採用TCP協議,也能夠採用UDP協議。
  • 應用層:主要負責應用程序的協議,例如HTTP協議、FTP協議等

 

(3)IP地址和端口號

IP地址:網絡中每一臺計算機的邏輯標識

端口號:區分計算機中的不一樣程序(0到65535)

總結:當咱們向別的計算機發送信息時咱們能夠經過IP地址找到計算機,經過端口號肯定應用程序

 

(4)InetAddress類使用

瞭解了IP地址的做用,咱們看學習下JDK中提供了一個InetAdderss類,該類用於封裝一個IP地址,並提供了

一系列與IP地址相關的方法,下表中列出了InetAddress類的一些經常使用方法:

上圖中,列舉了InetAddress的四個經常使用方法:

  • 前兩個方法用於得到該類的實例對象,
  • 第一個方法用於得到表示指定主機的InetAddress對象,
  • 第二個方法用於得到表示本地的InetAddress對象。
  • 另外經過InetAddress對象即可獲取指定主機名,IP地址等

接下來經過一個案例來演示InetAddress的經常使用方法,以下所示:

 1 import java.net.*;
 2 
 3 // INetAddress實例
 4 public class INetAddressDemo {
 5     public static void main(String[] args) throws UnknownHostException {
 6         InetAddress local = InetAddress.getLocalHost();
 7         System.out.println(local);      // 打印格式: 用戶名/IP地址
 8         InetAddress remote = InetAddress.getByName("www.baidu.com");
 9 
10         System.out.println("本機的IP地址:" + local.getHostAddress());
11         System.out.println("本機的主機名爲: " + local.getHostName());
12         System.out.println("itcast的IP地址:" + remote.getHostAddress());
13         System.out.println("itcast的主機名爲:" + remote.getHostName());
14     }
15 }

 

 

二、UDP與TCP

(1)UDP協議

UDP協議的特色是面向無鏈接的通訊協議,不保證數據的完整性

即在數據傳輸時,數據的發送端和接收端不創建邏輯鏈接。簡單來講,當一臺計算機向另一臺計算機

發送數據時,發送端不會確認接收端是否存在,就會發出數據,一樣接收端在收到數據時,也不會向發送端

反饋是否收到數據,例如:咱們的供屏軟件。

 

這種協議既然有那麼多缺點爲何還用它?

因爲使用UDP協議消耗資源小,通訊效率高,因此一般都會用於音頻、視頻和普通數據的傳輸例如視頻會議

使用UDP協議,由於這種狀況即便偶爾丟失一兩個數據包,也不會對接收結果產生太大影響。

但在使用UDP協議傳送數據時,因爲UDP的面向無鏈接性,不能保證數據的完整性,所以在傳輸重要數據時

不建議使用UDP協議。UDP的交換過程以下圖所示。

 

 

(2)TCP協議

TCP協議的特色是面向鏈接的通訊協議,保證數據的安全和完整性

即在傳輸數據前先在發送端和接收端創建邏輯鏈接,而後再傳輸數據,它提供了兩臺計算機之間可靠無差錯的

數據傳輸。在TCP鏈接中必須要明確客戶端與服務器端,由客戶端向服務端發出鏈接請求,每次鏈接的建立都

須要通過「三次握手」。第一次握手,客戶端向服務器端發出鏈接請求,等待服務器確認,第二次握手,服務器端

向客戶端回送一個響應,通知客戶端收到了鏈接請求,第三次握手,客戶端再次向服務器端發送確認信息,確認

鏈接。整個交互過程以下圖所示:

因爲TCP協議的面向鏈接特性,它能夠保證傳輸數據的安全性,因此是一個被普遍採用的協議,例如在下載文件時,

若是數據接收不完整,將會致使文件數據丟失而不能被打開,所以,下載文件時必須採用TCP協議

 

 

三、UDP通訊

在UPD通訊中有2個經常使用的類,一個是數據包類DatagramPacket,一個是數據包發送接收器類DatagramSocket

(1)DatagramPacket類

前面介紹了UDP是一種面向無鏈接的協議,所以,在通訊時發送端和接收端不用創建鏈接。UDP通訊的過程就像是

貨運公司在兩個碼頭間發送貨物同樣。在碼頭髮送和接收貨物時都須要使用集裝箱來裝載貨物,UDP通訊也是同樣,

發送和接收的數據也須要使用「集裝箱」進行打包,爲此JDK中提供了一個DatagramPacket類,該類的實例對象就至關於

一個集裝箱,用於封裝UDP通訊中發送或者接收的數據。

想要建立一個DatagramPacket對象,首先須要瞭解一下它的構造方法。在建立發送端和接收端的DatagramPacket對象時,

使用的構造方法有所不一樣,接收端的構造方法只須要接收一個字節數組來存放接收到的數據,而發送端的構造方法不但要

接收存放了發送數據的字節數組,還須要指定發送端IP地址和端口號。

構造方法以下:

經常使用方法以下:

 

(2)DatagramSocket類

DatagramPacket數據包的做用就如同是「集裝箱」,能夠將發送端或者接收端的數據封裝起來。然而運輸貨物只有

「集裝箱」是不夠的,還須要有碼頭。在程序中須要實現通訊只有DatagramPacket數據包也一樣不行,爲此JDK中

提供了DatagramSocket類,DatagramSocket類的做用就相似於碼頭,使用這個類的實例對象就能夠發送和接收

DatagramPacket數據包,發送數據的過程以下圖所示:

構造方法:

  • 發送端:構造方法中能夠指定端口號也能夠不指定端口號
  • 接收端:構造方法中必需要指定端口號

經常使用方法:

 

(3)UDP通訊程序

大體過程以下所示:

發送端代碼:

 1 import java.net.*;
 2 
 3 /*
 4  * 發送端:
 5  * 1,建立DatagramSocket對象
 6  * 2,建立DatagramPacket對象,並封裝數據
 7  * 3,發送數據
 8  * 4,釋放流資源
 9  */
10 
11 public class UDPSender {
12     public static void main(String[] args) throws Exception {
13         // 1,建立DatagramSocket對象
14         DatagramSocket ds = new DatagramSocket();
15         // 2,建立DatagramPacket對象,並封裝數據
16         // 構造數據報包,用來將長度爲 length 的包發送到指定主機上的指定端口號。
17         byte[] buffer = "hello, UDP".getBytes();
18         InetAddress ip = InetAddress.getByName("127.0.0.1");
19         int port = 12345;
20         DatagramPacket dp = new DatagramPacket(buffer, buffer.length, ip, port);
21         // 3,發送數據
22         ds.send(dp);
23         // 4,釋放流資源
24         ds.close();
25 
26     }
27 }

 

接收端代碼:

 1 import java.net.*;
 2 
 3 /*
 4  * UDP接收端
 5  * 
 6  * 1,建立DatagramSocket對象
 7  * 2,建立DatagramPacket對象
 8  * 3,接收數據存儲到DatagramPacket對象中
 9  * 4,獲取DatagramPacket對象的內容
10  * 5,釋放流資源
11  */
12 
13 public class UDPReceiver {
14     public static void main(String[] args) throws Exception{
15         // 1,建立DatagramSocket對象,並指定端口號
16         int port = 12345;
17         DatagramSocket ds = new DatagramSocket(port);
18         // 2,建立DatagramPacket對象, 建立一個空的倉庫
19         byte[] buffer = new byte[1024];
20         DatagramPacket dp = new DatagramPacket(buffer, 1024);
21         // 3,接收數據存儲到DatagramPacket對象中
22         System.out.println("等待發送端發送數據...");
23         ds.receive(dp);
24         // 4,獲取DatagramPacket對象的內容
25         InetAddress ipAddress = dp.getAddress();
26         String ip = ipAddress.getHostAddress();// 獲取到了IP地址
27         // 發來什麼數據 getData()以及發來多少數據 getLenth()
28         byte[] data = dp.getData();
29         int length = dp.getLength();
30         // 顯示收到的數據
31         String dataStr = new String(data, 0, length);
32         System.out.println("IP地址:" + ip + "數據是" + dataStr);
33         // 5,釋放流資源
34         ds.close();
35 
36     }
37 }

 

 

四、TCP通訊

TCP通訊同UDP通訊同樣,都能實現兩臺計算機之間的通訊,通訊的兩端都須要建立socket對象。

區別在於,UDP中只有發送端和接收端,不區分客戶端與服務器端,計算機之間能夠任意地發送數據

TCP通訊是嚴格區分客戶端與服務器端,在通訊時,必須先由客戶端去鏈接服務器端才能實現通訊,

服務器端不能夠主動鏈接客戶端,而且服務器端程序須要事先啓動,等待客戶端的鏈接。

在JDK中提供了兩個類用於實現TCP程序,一個是Socket類,用於表示客戶端,另外一個是ServerSocket類,用於表示服務器端。

通訊時,首先建立表明服務器端的ServerSocket對象,該對象至關於開啓一個服務,並等待客戶端的鏈接,

而後建立表明客戶端的Socket對象向服務器端發出鏈接請求,服務器端響應請求,二者創建鏈接開始通訊。

(1)ServerSocket

構造方法:

經常使用方法:

ServerSocket對象負責監聽某臺計算機的某個端口號,在建立ServerSocket對象後,須要繼續調用該對象的accept()方法,

接收來自客戶端的請求。當執行了accept()方法以後,服務器端程序會發生阻塞,直到客戶端發出鏈接請求,accept()方法

纔會返回一個Scoket對象用於和客戶端實現通訊,程序才能繼續向下執行。

 

(2)Socket

構造方法:

 

 經常使用方法:

在Socket類的經常使用方法中,getInputStream()和getOutStream()方法分別用於獲取輸入流和輸出流。當客戶端和服務端創建鏈接後,

數據是以IO流的形式進行交互的,從而實現通訊。

接下來經過一張圖來描述服務器端和客戶端的數據傳輸,以下圖所示:

 

(3)TCP通訊程序

服務器端:

 1 /*
 2  * TCP 服務器端
 3  * 
 4  * 1,建立服務器ServerSocket對象(指定服務器端口號)
 5  * 2,開啓服務器了,等待客戶端的鏈接,當客戶端鏈接後,能夠獲取到鏈接服務器的客戶端Socket對象
 6  * 3,給客戶端反饋信息
 7  * 4,關閉流資源
 8  */
 9 
10 import java.io.*;
11 import java.net.*;
12 
13 public class TCPServer {
14     public static void main(String[] args) throws IOException {
15         //1,建立服務器ServerSocket對象(指定服務器端口號)
16         ServerSocket ss = new ServerSocket(8888);
17         //2,開啓服務器了,等待客戶端的鏈接,當客戶端鏈接後,能夠獲取到鏈接服務器的客戶端Socket對象
18         Socket s = ss.accept();
19         //3,給客戶端反饋信息
20         /*
21          * a,獲取客戶端的輸出流
22          * b,在服務端端,經過客戶端的輸出流寫數據給客戶端
23          */
24         //a,獲取客戶端的輸出流
25         OutputStream out = s.getOutputStream();
26         //b,在服務端端,經過客戶端的輸出流寫數據給客戶端
27         out.write("你已經鏈接上了服務器".getBytes());
28         //4,關閉流資源
29         out.close();
30         s.close();
31         //ss.close();  服務器流 一般都是不關閉的
32     }
33 
34 }

 

客戶端:

 1 /*
 2  * TCP 客戶端
 3  * 
 4  * 1,建立客戶端Socket對象,(指定要鏈接的服務器地址與端口號)
 5  * 2,獲取服務器端的反饋回來的信息
 6  * 3,關閉流資源
 7  */
 8 
 9 import java.io.*;
10 import java.net.*;
11 
12 public class TCPClient {
13     public static void main(String[] args) throws IOException {
14         // 1,建立客戶端Socket對象,(指定要鏈接的服務器地址與端口號)
15         Socket s = new Socket("127.0.0.1", 8888);
16         // 2,獲取服務器端的反饋回來的信息
17         InputStream in = s.getInputStream();
18         // 把流中的數據存儲到數組中,並記錄讀取字節的個數
19         byte[] buffer = new byte[1024];
20         int length = in.read(buffer);
21         // 顯示數據
22         InetAddress ip = s.getInetAddress();
23         System.out.println(ip + new String(buffer, 0, length));
24         // 3,關閉流資源
25         in.close();
26         s.close();
27 
28     }
29 }

 

服務端和客戶端:

 

(4)文件上傳案例

文件上傳大體過程:

 1 import java.io.*;
 2 import java.net.*;
 3 
 4 public class FileUploadServer {
 5     public static void main(String[] args) throws IOException {
 6         //1,建立服務器,等待客戶端鏈接
 7         ServerSocket serverSocket = new ServerSocket(8888);
 8         Socket clientSocket = serverSocket.accept();
 9         //顯示哪一個客戶端Socket鏈接上了服務器
10         InetAddress ipObject = clientSocket.getInetAddress();//獲得IP地址對象
11         String ip = ipObject.getHostAddress(); //獲得IP地址字符串
12         System.out.println("客戶端的IP:" + ip);
13         
14         //2,獲取Socket的輸入流
15         InputStream in = clientSocket.getInputStream();
16         //3,建立目的地的字節輸出流  
17         BufferedOutputStream fileOut = new BufferedOutputStream(new FileOutputStream("D:\\upload\\" + System.currentTimeMillis() + ".jpg"));
18         //4,把Socket輸入流中的數據,寫入目的地的字節輸出流中
19         byte[] buffer = new byte[1024];
20         int len = -1;
21         while((len = in.read(buffer)) != -1){
22             //寫入目的地的字節輸出流中
23             fileOut.write(buffer, 0, len);
24         }
25         
26         //-----------------反饋信息---------------------
27         //5,獲取Socket的輸出流, 做用:寫反饋信息給客戶端
28         OutputStream out = clientSocket.getOutputStream();
29         //6,寫反饋信息給客戶端
30         out.write("圖片上傳成功".getBytes());
31         
32         out.close();
33         fileOut.close();
34         in.close();
35         clientSocket.close();
36         //serverSocket.close();
37     }
38 
39 }
 1 import java.io.*;
 2 import java.net.*;
 3 
 4 public class FileUploadClient {
 5     public static void main(String[] args) throws IOException {
 6         // 1,建立客戶端Socket,鏈接服務器
 7         Socket socket = new Socket("127.0.0.1", 8888);
 8         // 2,獲取Socket流中的輸出流,功能:用來把數據寫到服務器
 9         OutputStream out = socket.getOutputStream();
10         // 3,建立字節輸入流,功能:用來讀取數據源(圖片)的字節
11         BufferedInputStream fileIn = new BufferedInputStream(
12                 new FileInputStream("D:\\test.jpg"));
13         // 4,把圖片數據寫到Socket的輸出流中(把數據傳給服務器)
14         byte[] buffer = new byte[1024];
15         int len = -1;
16         while ((len = fileIn.read(buffer)) != -1) {
17             // 把數據寫到Socket的輸出流中
18             out.write(buffer, 0, len);
19         }
20         // 5,客戶端發送數據完畢,結束Socket輸出流的寫入操做,告知服務器端
21         socket.shutdownOutput();
22 
23         // -----------------反饋信息---------------------
24         // 6,獲取Socket的輸入流 做用: 讀反饋信息
25         InputStream in = socket.getInputStream();
26         // 7,讀反饋信息
27         byte[] info = new byte[1024];
28         // 把反饋信息存儲到info數組中,並記錄字節個數
29         int length = in.read(info);
30         // 顯示反饋結果
31         System.out.println(new String(info, 0, length));
32 
33         // 8,關閉流
34         in.close();
35         fileIn.close();
36         out.close();
37         socket.close();
38     }
39 
40 }

 

 

五、網絡編程總結

(1)基礎知識

  • IP地址:用來惟一表示咱們本身的電腦的,是一個網絡標示
  • 端口號: 用來區別當前電腦中的應用程序的
  • UDP: 傳送速度快,可是容易丟數據,如視頻聊天,語音聊天
  • TCP: 傳送穩定,不會丟失數據,如文件的上傳、下載

 

(2)UDP程序交互的流程

發送端:

1,建立DatagramSocket對象

2,建立DatagramPacket對象,並封裝數據

3,發送數據

4,釋放流資源

 

接收端:

1,建立DatagramSocket對象

2,建立DatagramPacket對象

3,接收數據存儲到DatagramPacket對象中

4,獲取DatagramPacket對象的內容

 5,釋放流資源

 

(3)TCP程序交互的流程

客戶端:

1,建立客戶端的Socket對象

2,獲取Socket的輸出流對象

3,寫數據給服務器

4,獲取Socket的輸入流對象

5,使用輸入流,讀反饋信息

6,關閉流資源

 

服務器端:

1,建立服務器端ServerSocket對象,指定服務器端端口號

2,開啓服務器,等待着客戶端Socket對象的鏈接,若有客戶端鏈接,返回客戶端的Socket對象

3,經過客戶端的Socket對象,獲取客戶端的輸入流,爲了實現獲取客戶端發來的數據

4,經過客戶端的輸入流,獲取流中的數據

5,經過客戶端的Socket對象,獲取客戶端的輸出流,爲了實現給客戶端反饋信息

6,經過客戶端的輸出流,寫數據到流中

7,關閉流資源

相關文章
相關標籤/搜索