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.發送方列印出接收方回報的消息
詳細思路見代碼:
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.SocketAddress;
public class Receive {
// 确定接受方的IP和端口号,IP位址為本地機器位址
// 建立接收方的套接字,并制定端口号和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();
測試已認證
先啟動接收方,然後啟動發送方即可