Express:模板引擎深入研究
UDP是User Datagram Protocol的簡稱,稱為使用者資料報協議,TCP是Transmission Control Protocol的簡稱,稱為傳輸控制協議。
UDP協議
UDP是無連線通訊協議,即在資料傳輸時,資料的傳送端和接收端不建立邏輯連線。簡單來說,當一臺計算機向另外一臺計算機發送資料時,傳送端不會確認接收端是否存在,就會發出資料,同樣接收端在收到資料時,也不會向傳送端反饋是否收到資料。
由於使用UDP協議消耗資源小,通訊效率高,所以通常都會用於音訊、視訊和普通資料的傳輸例如視訊會議都使用UDP協議,因為這種情況即使偶爾丟失一兩個資料包,也不會對接收結果產生太大影響。
但是在使用UDP協議傳送資料時,由於UDP的面向無連線性,不能保證資料的完整性,因此在傳輸重要資料時不建議使用UDP協議。UDP的交換過程如下圖所示。
UDP傳輸資料被限制在64K以內。
TCP協議
TCP協議是面向連線的通訊協議,即在傳輸資料前先在傳送端和接收端建立邏輯連線,然後再傳輸資料,它提供了兩臺計算機之間可靠無差錯的資料傳輸。在TCP連線中必須要明確客戶端與伺服器端,由客戶端向服務端發出連線請求,每次連線的建立都需要經過“三次握手”。第一次握手,客戶端向伺服器端發出連線請求,等待伺服器確認,第二次握手,伺服器端向客戶端回送一個響應,通知客戶端收到了連線請求,第三次握手,客戶端再次向伺服器端傳送確認資訊,確認連線。整個互動過程如下圖所示。
由於TCP協議的面向連線特性,它可以保證傳輸資料的安全性,所以是一個被廣泛採用的協議,例如在下載檔案時,如果資料接收不完整,將會導致檔案資料丟失而不能被開啟,因此,下載檔案時必須採用TCP協議。
UDP通訊
DatagramPacket
用於封裝UDP通訊中傳送或者接收的資料。
使用該構造方法在建立DatagramPacket物件時,指定了封裝資料的位元組陣列和資料的大小,沒有指定IP地址和埠號。很明顯,這樣的物件只能用於接收端,不能用於傳送端。因為傳送端一定要明確指出資料的目的地(ip地址和埠號),而接收端不需要明確知道資料的來源,只需要接收到資料即可。
使用該構造方法在建立DatagramPacket物件時,不僅指定了封裝資料的位元組陣列和資料的大小,還指定了資料包的目標IP
常用方法:
DatagramPacket
將傳送端或者接收端的資料封裝起來
該構造方法用於建立傳送端的DatagramSocket物件,在建立DatagramSocket物件時,並沒有指定埠號,此時,系統會分配一個沒有被其它網路程式所使用的埠號。
該構造方法既可以用於建立接收端的DatagramSocket物件,又可以建立傳送端的DatagramSocket物件,在建立接收端的DatagramSocket物件時,必須指定一個埠號
常用方法:
UDP完成資料的傳送:
/* * 傳送端 * 1,建立DatagramPacket物件,封裝資料,接收的地址和埠 * 2,建立DatagramSocket物件 * 3,呼叫DatagramSocket中的send方法,傳送資料包 * 4,關閉資源DatagramSocket */ public class UDPSend { public static void main(String[] args) throws IOException { //1,建立DatagramSocket物件 DatagramSocket sendSocket = new DatagramSocket(); //2,建立DatagramPacket物件,並封裝資料 //public DatagramPacket(byte[] buf, int length, InetAddress address, int port) //構造資料報包,用來將長度為 length 的包傳送到指定主機上的指定埠號。 byte[] buffer = "hello,UDP".getBytes(); DatagramPacket dp = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("192.168.75.58"), 12306); //3,傳送資料 //public void send(DatagramPacket p) 從此套接字傳送資料報包 sendSocket.send(dp); //4,釋放流資源 sendSocket.close(); } }
UDP完成資料的接收
/* * UDP接收端 * * 1,建立DatagramSocket物件,繫結埠號(要和傳送端埠號一致) * 2,建立位元組陣列,接收發來的資料 * 3,建立資料包物件DatagramPacket * 4,呼叫DatagramSocket物件方法receive(DatagramPacket dp)接收資料,資料放在資料包中 * 5,拆包 傳送的IP地址 資料包物件DatagramPacket方法getAddress()獲取的是傳送端的IP地址物件 返回值是InetAddress物件 接收到的位元組個數 資料包物件DatagramPacket方法getLength() 傳送方的埠號 資料包物件DatagramPacket方法getPort()傳送埠 * 6,關閉資源 */ public class UDPReceive { public static void main(String[] args) throws IOException { //1,建立DatagramSocket物件,並指定埠號 DatagramSocket receiveSocket = new DatagramSocket(12306); //2,建立DatagramPacket物件, 建立一個空的倉庫 byte[] buffer = new byte[1024]; DatagramPacket dp = new DatagramPacket(buffer, 1024); //3,接收資料儲存到DatagramPacket物件中 receiveSocket.receive(dp); //4,獲取DatagramPacket物件的內容 //誰發來的資料 getAddress() InetAddress ipAddress = dp.getAddress(); String ip = ipAddress.getHostAddress();//獲取到了IP地址 //發來了什麼資料 getData() byte[] data = dp.getData(); //發來了多少資料 getLenth() int length = dp.getLength(); //顯示收到的資料 String dataStr = new String(data,0,length); System.out.println("IP地址:"+ip+ "資料是"+ dataStr); //5,釋放流資源 receiveSocket.close(); } }