網絡編程之 udp
計算機網絡,就是把分布在不同地理區域的計算機與專門的外部設備用通信線路互連成一個規模大、功能強的網絡系統,從而使眾多的計算機可以方便地互相傳遞信息,共享硬件、軟件、數據信息等資源。
網絡體系結構:國際標準化組織 ISO 于 l978 年提出“開放系統互連參考模型”,即著名的 OSI ( OpenSystemInterconnection )模型。該模型把計算機網絡分成物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層、應用層等七層。
通信協議
計算機網絡中實現通信必須有一些約定,即通信協議。對速率、傳輸代碼、代碼結構、傳輸控制步驟、出錯控制等制定標準。
TCP 協議:提供可靠的數據傳輸服務的規則。
IP 協議進行 IP 數據包的分割和組裝。
但是通過 IP 協議并不能清楚地了解到數據包是否順利地發送給目標計算機。而使用 TCP 協議,它將數據包成功發送給目標計算機后,會要求發送一個確認,如果在某個時間內沒有收到確認, TCP 將重新發送數據包。
首先了解一下神馬是 UDP 協議 ;
UDP(UserDatagramProtocol) 協議是用戶數據報,在網絡中它與 TCP 協議一樣用于處理數據包。在 OSI 模型中,在第四層——傳輸層,處于 IP 協議的上一層。
UDP 是一種無連接的協議,每個數據報都是一個獨立的信息,包括完整的源或目的地址,它在網絡上以任何可能的路徑傳往目的地,因此能否到達目的地,到達目的地的時間以及內容的正確性都是不能被保證的。
為什么要使用 UDP ?
在網絡質量令人不十分滿意的環境下, UDP 協議數據包丟失會比較嚴重。但是由于 UDP 的特性:它不屬于連接型協議,因而具有資源消耗小,處理速度快的優點,所以通常音頻、視頻和普通數據在傳送時使用 UDP 較多,因為它們即使偶爾丟失一兩個數據包,也不會對接收結果產生太大影響。比如聊天用的 ICQ 和 OICQ 就是使用的 UDP 協議。
上網搜索摸個網站的時候,本機是先訪問本地的 hosts 文件區,去找該主機名是否有對應的 ip 地址;
C:\Windows\System32\drivers\etc\hosts; 在里面可以加上你經常進的網站和 ip ;
InetAddress :用于描述 IP 地址的對象
InetAddress
類沒有提供構造方法,而是提供了兩個靜態方法來獲取
InetAddress
實例
getByName(Stringhost)
:根據主機獲取對應的
InetAddress
對象。
getByAddress(byte[]addr)
:根據原始
IP
地址來獲取對應的
InetAddress
對象。
// 將指定 ip 封裝成 InetAddress 對象。
InetAddressia=InetAddress.getByName("127.0.0.1");
在
Java
中操縱
UDP
使用位于
JDK
中
Java.net
包下的
DatagramSocket
和
DatagramPacket
類,可以非常方便地控制用戶數據報文。
每個數據包的大小限制在 64k 內;
面向無連接,是不可靠協議,容易丟包;
不需要連接,速度快;
DatagramSocket 類:創建接收和發送 UDP 的 Socket 實例
DatagramSocket() :創建實例。通常用于客戶端編程,它并沒有特定監聽的端口,僅僅使用一個臨時的。
DatagramSocket(intport) :創建實例,并固定監聽 Port 端口的報文。
DatagramSocket(intport,InetAddresslocalAddr) :這是個非常有用的構建器,當一臺機器擁有多于一個 IP 地址的時候,由它創建的實例僅僅接收來自 LocalAddr 的報文。
receive(DatagramPacketd) :接收數據報文到 d 中。 receive 方法產生一個“阻塞”。
send(DatagramPacketd) :發送報文 d 到目的地。
setSoTimeout(inttimeout) :設置超時時間,單位為毫秒。
close()
:關閉
DatagramSocket
。在應用程序退出的時候,通常會主動釋放資源,關閉
Socket
,但是由于異常地退出可能造成資源無法回收。所以,應該在程序完成時,主動使用此方法關閉
Socket
,或在捕獲到異常拋出后關閉
Socket
。
建立一個 upd 的發送端。
用于發送數據。
1, 建立 updsocket 服務。
2 ,將數據封裝成數據包。
3 ,通過 socket 服務的 send 方法。將數據包發出。
4 ,關閉資源。
*/
//1, 建立 udpsocket 服務。
DatagramSocketds=newDatagramSocket;
//2, 將數據封裝成數據包。要使用 DatagramPacket 對象
//2.1 先將要發送的數據變成字節數組。在指定發送的目的地和端口。
//2.2 將這些信息作為參數傳遞給數據包對象的構造函數。
byte[]bf=”hahah,wolaile”.getBytes[];
InetAdressip=InetAdress.getName(“192.168.49.111”);
DatagramPacketdp=newDatagramPacket(bf,bf.getLength,ip,9909);
//3, 使用 Socket 服務的 send 方法將數據包發送出去。
Ds.send(dp);
//4, 關閉資源。
ds.close;
/*
建立 udp 的接收端。
1 ,建立 udp 接收端服務,必須要監聽一個端口,因為要明確,哪個端口來的數據是由該應用程序所處理的。
2 ,建立一個空的數據包,用于存儲接收到數據,
將字節數據存儲到數據包對象中,可以使用數據包對象的方法獲取不同的數據信息。
3 ,使用 Socket 服務的 receive 方法將接收到的數據存儲到數據包中。
4 ,通過數據包的方法獲取指定數據信息。
5 ,關閉資源。
*/
//1, 建立 updsocket 服務,監聽一個端口。
DatagramSocketds=newDatagramSocket(9909);
//2, 建立一個執行大小的數據包,用于存儲數據,以便獲取。
byte[]bf=newbyte[1024];
DatagramPacketdp=newDatagramPacket(bf,bf.getLength);
//3, 使用 socket 的 receive 方法將數據存儲到數據包中。
ds.receive();
//4, 通過數據包對象的方法獲取其中的數據。
Stringip=getAddress().getHostAdress();
Stringdata=newString(dp.getData(),0,dp.getLength);
intport=dp.getPort();
System.out.println(ip+”:”+data+”::”+port);
//5, 關閉資源。
ds.close();
package com.csdn.hbsi; /* 需求: 制作一個dos版的聊天程序。 1,對于聊天分兩個動作,接收和發送。 2,接收和發送都需要同時運行。這就使用到了多線程技術。 一個線程控制接收,一個線程控制發送。 3,既然要進行群聊。那么就要使用socket網絡服務。這里我們使用Udp完成。 */ import java.net.*; import java.io.*; class ChatSend implements Runnable { private DatagramSocket ds; ChatSend(DatagramSocket ds) { this.ds = ds; } public void run() { BufferedReader bufr = null; try { bufr = new BufferedReader(new InputStreamReader(System.in)); String line = null; while((line=bufr.readLine())!=null) { if("886".equals(line)) break; byte[] buf = line.getBytes(); DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.49.255"),9008); ds.send(dp); } ds.close(); }catch (Exception e) { System.out.println(e.toString()); } } } class ChatRece implements Runnable { private DatagramSocket ds; ChatRece(DatagramSocket ds){ this.ds = ds;<!--EndFragment--> } public void run(){ while(true){ try{ byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf,buf.length); ds.receive(dp); String ip = dp.getAddress().getHostAddress(); String data = new String(dp.getData(),0,dp.getLength()); System.out.println(ip+"::"+data); }catch (Exception e){ System.out.println(e.toString()); } } } } class ChatDemo { public static void main(String[] args) throws Exception{ DatagramSocket send = new DatagramSocket(); DatagramSocket rece = new DatagramSocket(9008); new Thread(new ChatSend(send)).start(); new Thread(new ChatRece(rece)).start(); } }
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
