一、UDP是什么?
UDP是User Datagram Protocol的简称,中文名是用户数据报协议,是OSI参考模型中的传输层协议,它是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,了对于UDP而言没有客户端和服务端的概念。
二、在java中UDP实现对话的流程
2. 接收时的逻辑:
三、源码实现
源码:
发送类(功能类):
package Dome.inet.udp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/**
* @author : HuXuehao
* @date : 2021年6月1日上午6:26:46
* @version :
*/
public class Send implements Runnable{
//此类表示用于发送和接收数据报数据包的套接字
DatagramSocket socket =null;
//BufferedReader : 从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取
BufferedReader reader =null;
//目标IP
private String toIP;
//目标端口
private int toPort;
//构造方法
public Send(String toIP, int toPort) {
this.toIP = toIP;
this.toPort = toPort;
try {
//1、套接创建字
socket = new DatagramSocket();
//2、在BufferedReader中包装一个InputStreamReader,用于读取输入台中的数据
reader = new BufferedReader(new InputStreamReader(System.in));
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(true) {
try {
//3、读取一行数据
String inform = reader.readLine();
//4、将String转成byte数组
byte[] bytes = inform.getBytes();
/*5、DatagramPacket:数据报包类
创建一个用于发送数据包的packet
bytes:要传输的数据
0~bytes.length:传输数据的具体范围
InetAddress.getByName(toIP):目标主机
toPort:目标主机的目标端口
*/
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length, InetAddress.getByName(toIP), toPort);
//6、发送数据报包
socket.send(packet);
if(inform.equals("exit")) {
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
//7、关闭套接字
socket.close();
}
}
接收类(功能类):
package Dome.inet.udp;
/**
* @author : HuXuehao
* @date : 2021年6月1日上午6:27:08
* @version :
*/
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Receive implements Runnable{
//此类表示用于发送和接收数据报数据包的套接字
DatagramSocket socket = null;
//开放的端口
private int openPort;
//发送数据包的名称
private String senderName;
//构造方法
public Receive(String senderName, int openPort) {
this.senderName = senderName;
this.openPort = openPort;
try {
//1、构造数据报套接字并将其绑定到本地主机上的指定端口
socket = new DatagramSocket(this.openPort);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(true) {
try {
//2、创建一个用于接收数据报包的容器
byte[] buffer = new byte[1024];
//3、数据报包类;DatagramPacket
//构造一个 DatagramPacket用于接收长度的分组 length ,
//指定偏移到缓冲器中
DatagramPacket packet = new DatagramPacket(buffer, 0,buffer.length);
//4、接收数据报包
socket.receive(packet);
//5、获取数据
byte[] data = packet.getData();
//将数据转成String
String inform = new String(data);
if(inform.equals("exit")) {
//打印数据
System.out.println(senderName+":我已经结束对话...");
break;
}else {
//打印数据
System.out.println(senderName+":"+inform);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//6、关闭套接字
socket.close();
}
}
员工类:
package Dome.inet.udp;
/**
* @author : HuXuehao
* @date : 2021年6月1日上午6:55:21
* @version :
*/
public class Employee {
public static void main(String[] args) {
System.out.println("【员工】");
//创建多线程
//9999:通过指定主机的9999端口进行传输
new Thread(new Send("localhost", 9999)).start();
//8888:开放自己的8888端口
new Thread(new Receive("老板", 8888)).start();
}
}
老板类:
package Dome.inet.udp;
/**
* @author : HuXuehao
* @date : 2021年6月1日上午6:55:44
* @version :
*/
public class Boss {
public static void main(String[] args) {
System.out.println("【老板】");
//创建多线程
//8888:通过指定主机的8888端口进行传输
new Thread(new Send("localhost", 8888)).start();
//9999:开放自己的9999端口
new Thread(new Receive("员工", 9999)).start();
}
}