Java網(wǎng)絡(luò)編程之UDP協(xié)議詳細(xì)解讀
UDP概述
UDP 是User Datagram Protocol的簡稱, 中文名是用戶數(shù)據(jù)報協(xié)議,是OSI(Open System Interconnection,開放式系統(tǒng)互聯(lián)) 參考模型中一種無連接的傳輸層協(xié)議,提供面向事務(wù)的簡單不可靠信息傳送服務(wù),IETF RFC 768是UDP的正式規(guī)范。UDP在IP報文的協(xié)議號是17。
UDP協(xié)議全稱是用戶數(shù)據(jù)報協(xié)議,在網(wǎng)絡(luò)中它與TCP協(xié)議一樣用于處理數(shù)據(jù)包,是一種無連接的協(xié)議。在OSI模型中,在第四層——傳輸層,處于IP協(xié)議的上一層。UDP有不提供數(shù)據(jù)包分組、組裝和不能對數(shù)據(jù)包進(jìn)行排序的缺點,也就是說,當(dāng)報文發(fā)送之后,是無法得知其是否安全完整到達(dá)的。UDP用來支持那些需要在計算機之間傳輸數(shù)據(jù)的網(wǎng)絡(luò)應(yīng)用。包括網(wǎng)絡(luò)視頻會議系統(tǒng)在內(nèi)的眾多的客戶/服務(wù)器模式的網(wǎng)絡(luò)應(yīng)用都需要使用UDP協(xié)議。UDP協(xié)議從問世至今已經(jīng)被使用了很多年,雖然其最初的光彩已經(jīng)被一些類似協(xié)議所掩蓋,但是即使是在今天UDP仍然不失為一項非常實用和可行的網(wǎng)絡(luò)傳輸層協(xié)議。
UDP主要特點
UDP是一個無連接協(xié)議,傳輸數(shù)據(jù)之前源端和終端不建立連接,當(dāng)它想傳送時就簡單地去抓取來自應(yīng)用程序的數(shù)據(jù),并盡可能快地把它扔到網(wǎng)絡(luò)上。在發(fā)送端,UDP傳送數(shù)據(jù)的速度僅僅是受應(yīng)用程序生成數(shù)據(jù)的速度、計算機的能力和傳輸帶寬的限制;在接收端,UDP把每個消息段放在隊列中,應(yīng)用程序每次從隊列中讀一個消息段。
由于傳輸數(shù)據(jù)不建立連接,因此也就不需要維護(hù)連接狀態(tài),包括收發(fā)狀態(tài)等,因此一臺服務(wù)機可同時向多個客戶機傳輸相同的消息。
UDP信息包的標(biāo)題很短,只有8個字節(jié),相對于TCP的20個字節(jié)信息包而言UDP的額外開銷很小。
吞吐量不受擁擠控制算法的調(diào)節(jié),只受應(yīng)用軟件生成數(shù)據(jù)的速率、傳輸帶寬、源端和終端主機性能的限制。
UDP是面向報文的。發(fā)送方的UDP對應(yīng)用程序交下來的報文,在添加首部后就向下交付給IP層。既不拆分,也不合并,而是保留這些報文的邊界,因此,應(yīng)用程序需要選擇合適的報文大小。
雖然UDP是一個不可靠的協(xié)議,但它是分發(fā)信息的一個理想?yún)f(xié)議。例如,在屏幕上報告股票市場、顯示航空信息等等。UDP也用在路由信息協(xié)議RIP(Routing Information Protocol)中修改路由表。在這些應(yīng)用場合下,如果有一個消息丟失,在幾秒之后另一個新的消息就會替換它。UDP廣泛用在多媒體應(yīng)用中。
TCP和UDP區(qū)別
TCP 是面向連接的傳輸控制協(xié)議,而UDP 提供了無連接的數(shù)據(jù)報服務(wù);
TCP 具有高可靠性,確保傳輸數(shù)據(jù)的正確性,不出現(xiàn)丟失或亂序,而UDP 在傳輸數(shù)據(jù)前不建立連接,不對數(shù)據(jù)報進(jìn)行檢查與修改,無須等待對方的應(yīng)答,所以會出現(xiàn)分組丟失、重復(fù)、亂序,應(yīng)用程序需要負(fù)責(zé)傳輸可靠性方面的所有工作;
UDP 具有較好的實時性,工作效率較 TCP 協(xié)議高;
UDP 段結(jié)構(gòu)比 TCP 的段結(jié)構(gòu)簡單,因此網(wǎng)絡(luò)開銷也??;
TCP 協(xié)議可以保證接收端毫無差錯地接收到發(fā)送端發(fā)出的字節(jié)流,為應(yīng)用程序提供可靠的通信服務(wù)。對可靠性要求高的通信系統(tǒng)往往使用 TCP 傳輸數(shù)據(jù)。
應(yīng)用
適用場合
在選擇UDP作為傳輸協(xié)議時必須要謹(jǐn)慎。在網(wǎng)絡(luò)質(zhì)量令人十分不滿意的環(huán)境下,UDP協(xié)議數(shù)據(jù)包丟失會比較嚴(yán)重。但是由于UDP的特性:它不屬于連接型協(xié)議,因而具有資源消耗小,處理速度快的優(yōu)點,所以通常音頻、視頻和普通數(shù)據(jù)在傳送時使用UDP較多,因為它們即使偶爾丟失一兩個數(shù)據(jù)包,也不會對接收結(jié)果產(chǎn)生太大影響。比如我們聊天用的ICQ和QQ就是使用的UDP協(xié)議。
實際應(yīng)用
在現(xiàn)場測控領(lǐng)域,面向的是分布化的控制器、監(jiān)測器等,其應(yīng)用場合環(huán)境比較惡劣,這樣就對待傳輸數(shù)據(jù)提出了不同的要求,如實時、抗干擾性、安全性等?;诖?,現(xiàn)場通信中,若某一應(yīng)用要將一組數(shù)據(jù)傳送給網(wǎng)絡(luò)中的另一個節(jié)點,可由UDP進(jìn)程將數(shù)據(jù)加上報頭后傳送給IP進(jìn)程,UDP協(xié)議省去了建立連接和拆除連接的過程,取消了重發(fā)檢驗機制,能夠達(dá)到較高的通信速率。
代碼演示
簡單的一個客戶端/服務(wù)端數(shù)據(jù)收發(fā)的例子
UDP客戶端:
public class UdpClient { public static void main(String[] args) throws IOException { //建立一個socket DatagramSocket socket = new DatagramSocket(); //創(chuàng)建一個數(shù)據(jù)包 String msg = "你好啊,服務(wù)器~"; InetAddress localhost = InetAddress.getByName("localhost"); int port = 9090; DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port); //發(fā)送數(shù)據(jù)包 socket.send(packet); //關(guān)閉流 socket.close(); } }
UDP服務(wù)端:
public class UdpServer { public static void main(String[] args) throws IOException { //開啟端口 DatagramSocket socket = new DatagramSocket(9090); //接收數(shù)據(jù)包 byte[] bytes = new byte[1024]; DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length); //阻塞接收 socket.receive(packet); String msg = new String(packet.getData(),0,packet.getLength()); System.out.println("接收到客戶端發(fā)來的數(shù)據(jù):" + msg); //關(guān)閉數(shù)據(jù)流 socket.close(); } }
模擬一個學(xué)生和老師的聊天對話
//客戶端 public class TalkSend implements Runnable { DatagramSocket socket = null; BufferedReader br = null; private int formPort; private String toIp; private int toPort; public TalkSend(int formPort, String toIp, int toPort) { this.formPort = formPort; this.toIp = toIp; this.toPort = toPort; try { socket = new DatagramSocket(this.formPort); //準(zhǔn)備數(shù)據(jù) 控制臺讀取System.in br = new BufferedReader(new InputStreamReader(System.in)); } catch (SocketException e) { e.printStackTrace(); } } @Override public void run() { while (true) { try { String msg = br.readLine(); byte[] bytes = msg.getBytes(); DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length, new InetSocketAddress(this.toIp, this.toPort)); //發(fā)送數(shù)據(jù) socket.send(packet); if (msg.equals("bye")) { break; } } catch (IOException e) { e.printStackTrace(); } } socket.close(); } }
//服務(wù)端 public class TalkReceive implements Runnable { DatagramSocket socket = null; private int port; private String msgForm; public TalkReceive(int port, String msgForm) { this.port = port; this.msgForm = msgForm; try { socket = new DatagramSocket(port); } catch (SocketException e) { e.printStackTrace(); } } @Override public void run() { while (true) { try { //準(zhǔn)備接收包裹 byte[] bytes = new byte[1024]; DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length); socket.receive(packet); //斷開連接 bye String msg = new String(packet.getData(), 0, packet.getLength()); System.out.println(msgForm + ":" + msg); if ("bye".equals(msg)) { break; } } catch (IOException e) { e.printStackTrace(); } } socket.close(); } }
public class TalkStudent { public static void main(String[] args) { new Thread(new TalkSend(7777,"localhost",8888)).start(); new Thread(new TalkReceive(9999,"老師")).start(); } }
public class TalkTeacher { public static void main(String[] args) { new Thread(new TalkSend(5555,"localhost",9999)).start(); new Thread(new TalkReceive(8888,"學(xué)生")).start(); } }
測試一下,結(jié)果如下:
總結(jié)
- UDP用戶數(shù)據(jù)報協(xié)議,是面向無連接的通訊協(xié)議,UDP數(shù)據(jù)包括目的端口號和源端口號信息,由于通訊不需要連接,所以可以實現(xiàn)廣播發(fā)送。
- UDP通訊時不需要接收方確認(rèn),屬于不可靠的傳輸,可能會出現(xiàn)丟包現(xiàn)象,實際應(yīng)用中要求程序員編程驗證。
到此這篇關(guān)于Java網(wǎng)絡(luò)編程之UDP協(xié)議詳細(xì)解讀的文章就介紹到這了,更多相關(guān)UDP協(xié)議內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用IDEA搭建Hadoop開發(fā)環(huán)境的操作步驟(Window10為例)
經(jīng)過三次重裝,查閱無數(shù)資料后成功完成hadoop在win10上實現(xiàn)偽分布式集群,以及IDEA開發(fā)環(huán)境的搭建。一步一步跟著本文操作可以避免無數(shù)天坑2021-07-07IntelliJ IDEA(或者JetBrains PyCharm)中彈出"IntelliJ IDEA License
今天小編就為大家分享一篇關(guān)于IntelliJ IDEA(或者JetBrains PyCharm)中彈出"IntelliJ IDEA License Activation"的解決辦法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-10-10Spring?Cloud?Gateway動態(tài)路由Apollo實現(xiàn)詳解
這篇文章主要為大家介紹了Spring?Cloud?Gateway動態(tài)路由通過Apollo實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10詳解Java中使用ImageIO類對圖片進(jìn)行壓縮的方法
這篇文章主要介紹了Java中使用ImageIO類對圖片進(jìn)行壓縮的方法,能夠按指定的比例調(diào)整圖片的寬高,需要的朋友可以參考下2016-04-04Java邏輯運算符之&&、||?與&、?|的區(qū)別及應(yīng)用
這篇文章主要介紹了Java邏輯運算符之&&、||?與&、?|的區(qū)別及應(yīng)用的相關(guān)資料,分別是&&、||?與&、?|,并探討了它們在不同應(yīng)用場景中的表現(xiàn)和優(yōu)化效果,需要的朋友可以參考下2025-03-03Java語言實現(xiàn)簡單FTP軟件 FTP本地文件管理模塊實現(xiàn)(9)
這篇文章主要為大家詳細(xì)介紹了Java語言實現(xiàn)簡單FTP軟件,F(xiàn)TP本地文件管理模塊的實現(xiàn)方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04