1. UDP收發的基本操作
資料報的大小限制在64K之内。
- 封包的接收
System.out.println("接收方啟動中.....");
// 1、使用DatagramSocket 指定端口 建立接收端
DatagramSocket server =new DatagramSocket(6666); //伺服器端偵聽的端口
// 2、準備容器 封裝成DatagramPacket 包裹
byte[] container =new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3、阻塞式接收包裹receive(DatagramPacket p)
server.receive(packet); //阻塞式
// 4、分析資料
// byte[] getData()
// getLength()
byte[] datas =packet.getData();
int len = packet.getLength();
System.out.println(new String(datas,0,len));
// 5、釋放資源
server.close();
- 封包的發送
System.out.println("發送方啟動中.....");
// 1、使用DatagramSocket 指定端口 建立發送端
DatagramSocket client =new DatagramSocket(8888); //發送端的源端口
//2、準備資料 一定轉成位元組數組
String data = "黑夜給了我黑色的眼睛";
byte[] datas = data.getBytes("UTF8");
//3、 封裝成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
new InetSocketAddress("localhost",6666)); //發送端的目的位址和端口号
//4、發送包裹send(DatagramPacket p) *
client.send(packet);
// 5、釋放資源
client.close();
- 如何在eclipse中開啟多個console視窗
- 拖動調整Console視窗的位置,然後釘住
- 選擇console控制台視窗

2. UDP收發基本資料類型
- 封包的接收
System.out.println("接收方啟動中.....");
// 1、使用DatagramSocket 指定端口 建立接收端
DatagramSocket server =new DatagramSocket(6666);
// 2、準備容器 封裝成DatagramPacket 包裹
byte[] container =new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3、阻塞式接收包裹receive(DatagramPacket p)
server.receive(packet); //阻塞式
// 4、分析資料 将位元組數組還原為對應的類型
// byte[] getData()
// getLength()
byte[] datas =packet.getData();
int len = packet.getLength();
DataInputStream dis =new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
//順序與寫出一緻
String msg = dis.readUTF();
int age = dis.readInt();
boolean flag = dis.readBoolean();
char ch = dis.readChar();
System.out.println(msg+"-->"+flag);
// 5、釋放資源
server.close();
- 封包的發送
System.out.println("發送方啟動中.....");
// 1、使用DatagramSocket 指定端口 建立發送端
DatagramSocket client =new DatagramSocket(8888);
//2、準備資料 一定轉成位元組數組
//寫出
ByteArrayOutputStream baos =new ByteArrayOutputStream();
DataOutputStream dos =new DataOutputStream(new BufferedOutputStream(baos));
//操作資料類型 +資料
dos.writeUTF("編碼辛酸淚");
dos.writeInt(18);
dos.writeBoolean(false);
dos.writeChar('a');
dos.flush();
byte[] datas =baos.toByteArray();
//3、 封裝成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
new InetSocketAddress("localhost",6666));
//4、發送包裹send(DatagramPacket p) *
client.send(packet);
// 5、釋放資源
client.close();
3. UDP收發對象
- 封包的接收
System.out.println("接收方啟動中.....");
// 1、使用DatagramSocket 指定端口 建立接收端
DatagramSocket server =new DatagramSocket(6666);
// 2、準備容器 封裝成DatagramPacket 包裹
byte[] container =new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3、阻塞式接收包裹receive(DatagramPacket p)
server.receive(packet); //阻塞式
// 4、分析資料 将位元組數組還原為對應的類型
byte[] datas =packet.getData();
int len = packet.getLength();
//讀取 -->反序列化
ObjectInputStream ois =new ObjectInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
//順序與寫出一緻,對象的資料還原
Object str = ois.readObject();
Object date = ois.readObject();
Object employee = ois.readObject();
if(str instanceof String) {
String strObj = (String) str;
System.out.println(strObj);
}
if(date instanceof Date) {
Date dateObj = (Date) date;
System.out.println(dateObj);
}
if(employee instanceof Employee) {
Employee empObj = (Employee) employee;
System.out.println(empObj.getName()+"-->"+empObj.getSalary());
}
// 5、釋放資源
server.close();
- 封包的發送
System.out.println("發送方啟動中.....");
// 1、使用DatagramSocket 指定端口 建立發送端
DatagramSocket client =new DatagramSocket(8888);
//2、準備資料 一定轉成位元組數組
//寫出
ByteArrayOutputStream baos =new ByteArrayOutputStream();
ObjectOutputStream oos =new ObjectOutputStream(new BufferedOutputStream(baos));
//對象
oos.writeObject("我卻用它來尋找光明");
oos.writeObject(new Date());
Employee emp =new Employee("歐陽克",400);
oos.writeObject(emp);
oos.flush();
byte[] datas =baos.toByteArray();
//3、 封裝成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
new InetSocketAddress("localhost",6666));
//4、發送包裹
client.send(packet);
// 5、釋放資源
client.close();
4. 傳輸檔案(小檔案)
- 工具類
public class IOUtils {
/**
* 1、圖檔讀取到位元組數組
* 1)、圖檔到程式 FileInputStream
* 2)、程式到位元組數組 ByteArrayOutputStream
*/
public static byte[] fileToByteArray(String filePath) {
//1、建立源與目的地
File src = new File(filePath);
byte[] dest =null;
//2、選擇流
InputStream is =null;
ByteArrayOutputStream baos =null;
try {
is =new FileInputStream(src);
baos = new ByteArrayOutputStream();
//3、操作 (分段讀取)
byte[] flush = new byte[1024*10]; //緩沖容器
int len = -1; //接收長度
while((len=is.read(flush))!=-1) {
baos.write(flush,0,len); //寫出到位元組數組中
}
baos.flush();
return baos.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//4、釋放資源
try {
if(null!=is) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* 2、位元組數組寫出到圖檔
* 1)、位元組數組到程式 ByteArrayInputStream
* 2)、程式到檔案 FileOutputStream
*/
public static void byteArrayToFile(byte[] src,String filePath) {
//1、建立源
File dest = new File(filePath);
//2、選擇流
InputStream is =null;
OutputStream os =null;
try {
is =new ByteArrayInputStream(src);
os = new FileOutputStream(dest);
//3、操作 (分段讀取)
byte[] flush = new byte[5]; //緩沖容器
int len = -1; //接收長度
while((len=is.read(flush))!=-1) {
os.write(flush,0,len); //寫出到檔案
}
os.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
//4、釋放資源
try {
if (null != os) {
os.close();
}
} catch (Exception e) {
}
}
}
}
- 檔案的接收
System.out.println("接收方啟動中.....");
// 1、使用DatagramSocket 指定端口 建立接收端
DatagramSocket server =new DatagramSocket(6666);
// 2、準備容器 封裝成DatagramPacket 包裹
byte[] container =new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3、阻塞式接收包裹receive(DatagramPacket p)
server.receive(packet); //阻塞式
// 4、分析資料 将位元組數組還原為對應的類型
// byte[] getData()
// getLength()
byte[] datas =packet.getData();
int len = packet.getLength();
IOUtils.byteArrayToFile(datas, "src/copy.png");
// 5、釋放資源
server.close();
- 檔案的發送
System.out.println("發送方啟動中.....");
// 1、使用DatagramSocket 指定端口 建立發送端
DatagramSocket client =new DatagramSocket(8888);
//2、準備資料 一定轉成位元組數組
byte[] datas =IOUtils.fileToByteArray("src/logo.png");
//3、 封裝成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
new InetSocketAddress("localhost",6666));
//4、發送包裹send(DatagramPacket p) *
client.send(packet);
// 5、釋放資源
client.close();
5. 多次發送,多次接收
- 接收端
System.out.println("接收方啟動中.....");
// 1、使用DatagramSocket 指定端口 建立接收端
DatagramSocket server =new DatagramSocket(6666);
while(true) {
// 2、準備容器 封裝成DatagramPacket 包裹
byte[] container =new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3、阻塞式接收包裹receive(DatagramPacket p)
server.receive(packet); //阻塞式
// 4、分析資料
// byte[] getData()
// getLength()
byte[] datas =packet.getData();
int len = packet.getLength();
String data=new String(datas,0,len);
System.out.println(data);
if(data.equals("bye")) {
break;
}
}
// 5、釋放資源
server.close();
- 發送端
System.out.println("發送方啟動中.....");
// 1、使用DatagramSocket 指定端口 建立發送端
DatagramSocket client =new DatagramSocket(8888);
//2、準備資料 一定轉成位元組數組
BufferedReader reader =new BufferedReader(new InputStreamReader(System.in));
while(true) {
String data = reader.readLine();
byte[] datas = data.getBytes();
//3、 封裝成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
new InetSocketAddress("localhost",6666));
//4、發送包裹send(DatagramPacket p) *
client.send(packet);
if(data.equals("bye")) {
break;
}
}
// 5、釋放資源
client.close();
6. 全雙工通信
- 接收器
public class TalkReceive implements Runnable {
private DatagramSocket server;
private String from;
public TalkReceive(int port, String from) {
this.from = from;
try {
server = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true) {
byte[] container = new byte[1024 * 60];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
try {
server.receive(packet);// 阻塞式接收
byte[] datas = packet.getData();
int len = packet.getLength();
String data = new String(datas, 0, len);
System.out.println(from + ":" + data);
if (data.equals("bye")) {
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
server.close();
}
}
- 發送器
public class TalkSend implements Runnable {
private DatagramSocket client;
private BufferedReader reader;
private String destIP;
private int destPort;
public TalkSend(int srcPort, String destIP, int destPort) {
this.destIP = destIP;
this.destPort = destPort;
try {
client = new DatagramSocket(srcPort);
reader = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true) {
String data;
try {
data = reader.readLine(); // 阻塞讀取控制台輸入
byte[] datas = data.getBytes();
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
new InetSocketAddress(this.destIP, this.destPort));
client.send(packet);
if (data.equals("bye")) {
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
client.close();
}
}
- 對等通信端(屌絲 )
new Thread(new TalkSend(6100, "localhost", 8847)).start(); // 發送
new Thread(new TalkReceive(8848, "長腿皮褲妹")).start(); // 接收
- 對等通信端(長腿皮褲妹)
new Thread(new TalkSend(6120, "localhost", 8848)).start(); // 發送
new Thread(new TalkReceive(8847, "屌絲")).start(); // 接收