閱讀354 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Java中的DatagramPacket與DatagramSocket的初步

 

1.基本概念:

  a.DatagramPacket與DatagramSocket位於java.net包中

  b.DatagramPacket表示存放數據的數據報,DatagramSocket表示接受或發送數據報的套接字

  c.由這兩個類所有構成的網絡鏈接是基於UDP協議,是一種不可靠的協議。

  之所以不可靠是因為發送方不負責數據是否發送成功,接收方收到數據時也不會   向發送方反饋成功消息,容易導致信息的丟失。

  但是這種協議卻是快捷的,比如CS(半條命)遊戲就是基於UDP協議,否則我們估計   要玩一次遊戲後就會把機子砸了,所以我們可以看到遊戲有時會失幀。

  2.使用方法:

  要建立基於UDP協議的鏈接,我們應該先建立套接字<DatagramSocket>(即發送站或接收站),之後通過套接字發送或接受數據<DatagramPacket>。

  我們先了解一下DatagramSocket和DatagramPacket類

  DatagramSocket類:

  構造方法:

  DatagramSocket():

  表示創建一個默認的套接字,並綁定到本地地址和一個隨機的端口號

  DatagramSocket(int port):

  與上麵不同的是,綁定到特定端口號,其它不變

  DatagramSocket(int port, InetAddress iad):

  表示創建一個套接字,綁定到特定的端口號及指定地址

  DatagramSocket(SocketAddress sad);

  表示創建一個套接字,綁定到特定的套接字地址

  小提示:所謂的本地地址我們可以這樣來理解,我們通過“控製麵板-本地連接-支持”中可以看到一個IP地址,這就是本地的IP地址,也暫且理解為本地地址。

  基本方法:

  close():

  關閉套接字

  recevie(DatagramPacket dp):

  接受數據報

  send(DatagramPacket dp):

 發送數據報

  這裏觸及了數據報,下麵介紹數據報:

  DatagramPacket類:

  構造方法:(隻列出主要的)

  接受類型:

  DatagramPacket(byte[] buf, int length):

  用來接受長度為length的buf數據(即數據存於字節數組buf中)

  發送類型:

  DatagramPacket(byte[] buf, int length, InetAddress address, int port);

  將length長的buf數據發送到指定的地址的端口號處

  DatagramPacket(byte[] buf, int length, SocketAddress address);

   將length長的buf數據發送到指定的套接字地址處

  有上麵可知,我們發送數據時構造的數據報應該是發送類型的,而接受數據報時應該是接受類型的    

  開始書寫代碼

  代碼意圖:

  1.一個接收方,一個發送方

  2.當接收方收到發送方發送的消息後,打印發送的消息及發送方的地址和端口號,之後向發送反饋一條信息“接受方:我收到了!”

  3.發送方打印出接收方反饋的消息

  詳細思路見代碼:

  1. import java.net.DatagramPacket;  
  2. import java.net.DatagramSocket;  
  3. import java.net.InetAddress;  
  4.   
  5. public class Sender {  
  6.     public static void main(String[] args) {  
  7.         try {  
  8.             // 創建發送方的套接字,IP默認為本地,端口號隨機   
  9.             DatagramSocket sendSocket = new DatagramSocket();  
  10.   
  11.             // 確定要發送的消息:   
  12.             String mes = "你好!接收方!";  
  13.   
  14.             // 由於數據報的數據是以字符數組傳的形式存儲的,所以傳轉數據   
  15.             byte[] buf = mes.getBytes();  
  16.   
  17.             // 確定發送方的IP地址及端口號,地址為本地機器地址   
  18.             int port = 8888;  
  19.             InetAddress ip = InetAddress.getLocalHost();  
  20.   
  21.             // 創建發送類型的數據報:   
  22.             DatagramPacket sendPacket = new DatagramPacket(buf, buf.length, ip,  
  23.                     port);  
  24.   
  25.             // 通過套接字發送數據:   
  26.             sendSocket.send(sendPacket);  
  27.   
  28.             // 確定接受反饋數據的緩衝存儲器,即存儲數據的字節數組   
  29.             byte[] getBuf = new byte[1024];  
  30.   
  31.             // 創建接受類型的數據報   
  32.             DatagramPacket getPacket = new DatagramPacket(getBuf, getBuf.length);  
  33.   
  34.             // 通過套接字接受數據   
  35.             sendSocket.receive(getPacket);  
  36.   
  37.             // 解析反饋的消息,並打印   
  38.             String backMes = new String(getBuf, 0, getPacket.getLength());  
  39.             System.out.println("接受方返回的消息:" + backMes);  
  40.   
  41.             // 關閉套接字   
  42.             sendSocket.close();  
  43.         } catch (Exception e) {  
  44.             e.printStackTrace();  
  45.         }  
  46.   
  47.     }  
  48. }  
  49.   
  50.   
  51.   
  52. import java.net.DatagramPacket;  
  53. import java.net.DatagramSocket;  
  54. import java.net.InetAddress;  
  55. import java.net.SocketAddress;  
  56.   
  57. public class Receive {  
  58.     public static void main(String[] args) {  
  59.         try {  
  60.             // 確定接受方的IP和端口號,IP地址為本地機器地址   
  61.             InetAddress ip = InetAddress.getLocalHost();  
  62.             int port = 8888;  
  63.   
  64.             // 創建接收方的套接字,並製定端口號和IP地址   
  65.             DatagramSocket getSocket = new DatagramSocket(port, ip);  
  66.   
  67.             // 確定數據報接受的數據的數組大小   
  68.             byte[] buf = new byte[1024];  
  69.   
  70.             // 創建接受類型的數據報,數據將存儲在buf中   
  71.             DatagramPacket getPacket = new DatagramPacket(buf, buf.length);  
  72.   
  73.             // 通過套接字接收數據   
  74.             getSocket.receive(getPacket);  
  75.   
  76.             // 解析發送方傳遞的消息,並打印   
  77.             String getMes = new String(buf, 0, getPacket.getLength());  
  78.             System.out.println("對方發送的消息:" + getMes);  
  79.   
  80.             // 通過數據報得到發送方的IP和端口號,並打印   
  81.             InetAddress sendIP = getPacket.getAddress();  
  82.             int sendPort = getPacket.getPort();  
  83.             System.out.println("對方的IP地址是:" + sendIP.getHostAddress());  
  84.             System.out.println("對方的端口號是:" + sendPort);  
  85.   
  86.             // 通過數據報得到發送方的套接字地址   
  87.             SocketAddress sendAddress = getPacket.getSocketAddress();  
  88.   
  89.             // 確定要反饋發送方的消息內容,並轉換為字節數組   
  90.             String feedback = "接收方說:我收到了!";  
  91.             byte[] backBuf = feedback.getBytes();  
  92.   
  93.             // 創建發送類型的數據報   
  94.             DatagramPacket sendPacket = new DatagramPacket(backBuf,  
  95.                     backBuf.length, sendAddress);  
  96.   
  97.             // 通過套接字發送數據   
  98.             getSocket.send(sendPacket);  
  99.   
  100.             // 關閉套接字   
  101.             getSocket.close();  
  102.         } catch (Exception e) {  
  103.             e.printStackTrace();  
  104.         }  
  105.     }  
  106. }  
import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class Sender { public static void main(String[] args) { try { // 創建發送方的套接字,IP默認為本地,端口號隨機 DatagramSocket sendSocket = new DatagramSocket(); // 確定要發送的消息: String mes = "你好!接收方!"; // 由於數據報的數據是以字符數組傳的形式存儲的,所以傳轉數據 byte[] buf = mes.getBytes(); // 確定發送方的IP地址及端口號,地址為本地機器地址 int port = 8888; InetAddress ip = InetAddress.getLocalHost(); // 創建發送類型的數據報: DatagramPacket sendPacket = new DatagramPacket(buf, buf.length, ip, port); // 通過套接字發送數據: sendSocket.send(sendPacket); // 確定接受反饋數據的緩衝存儲器,即存儲數據的字節數組 byte[] getBuf = new byte[1024]; // 創建接受類型的數據報 DatagramPacket getPacket = new DatagramPacket(getBuf, getBuf.length); // 通過套接字接受數據 sendSocket.receive(getPacket); // 解析反饋的消息,並打印 String backMes = new String(getBuf, 0, getPacket.getLength()); System.out.println("接受方返回的消息:" + backMes); // 關閉套接字 sendSocket.close(); } catch (Exception e) { e.printStackTrace(); } } } import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketAddress; public class Receive { public static void main(String[] args) { try { // 確定接受方的IP和端口號,IP地址為本地機器地址 InetAddress ip = InetAddress.getLocalHost(); int port = 8888; // 創建接收方的套接字,並製定端口號和IP地址 DatagramSocket getSocket = new DatagramSocket(port, ip); // 確定數據報接受的數據的數組大小 byte[] buf = new byte[1024]; // 創建接受類型的數據報,數據將存儲在buf中 DatagramPacket getPacket = new DatagramPacket(buf, buf.length); // 通過套接字接收數據 getSocket.receive(getPacket); // 解析發送方傳遞的消息,並打印 String getMes = new String(buf, 0, getPacket.getLength()); System.out.println("對方發送的消息:" + getMes); // 通過數據報得到發送方的IP和端口號,並打印 InetAddress sendIP = getPacket.getAddress(); int sendPort = getPacket.getPort(); System.out.println("對方的IP地址是:" + sendIP.getHostAddress()); System.out.println("對方的端口號是:" + sendPort); // 通過數據報得到發送方的套接字地址 SocketAddress sendAddress = getPacket.getSocketAddress(); // 確定要反饋發送方的消息內容,並轉換為字節數組 String feedback = "接收方說:我收到了!"; byte[] backBuf = feedback.getBytes(); // 創建發送類型的數據報 DatagramPacket sendPacket = new DatagramPacket(backBuf, backBuf.length, sendAddress); // 通過套接字發送數據 getSocket.send(sendPacket); // 關閉套接字 getSocket.close(); } catch (Exception e) { e.printStackTrace(); } } }

 

測試已通過

  先啟動接收方,然後啟動發送方即可

最後更新:2017-04-02 06:52:18

  上一篇:go JAVA數據結構與算法-第一章-綜述
  下一篇:go Hibernate的Cascade——級聯操作