UDP编程
【简介】UDP:User Datagram Protocol
用户数据报协议。是一种不可靠,面向无连接的传输层
通信协议;
【特点】
<1>面向无连接
<2>不可靠传输 :UDP仅仅在数据报的头部,添加了复用和数据校验;
<3>每次内容不能超过64KB
<4>性能高效
【底层】
<1>Ftp协议底层udp;
<2>Http协议 底层tcp;
【java实现UDP】
Java支持udp协议,对UDP进行类的封装
①DatagramPacket
数据报包 :主要是包含要发送或者接收的数据;和对应数据的IP地址和端口号;数据报包用来实现无连接包投递服务;每条报文仅仅根据该包中包含的信息从一台机器路由到另一台机器;从一台机器发送到另一台机器的多个包可能选择不同的路由;也可能按不同的顺序到达;不对包投递做出保证;
构造函数:
<1>接收数据的数据报包:
DatagramPacket(byte[] buf,int length);
<2>发送数据的数据报包:DatagramPacket(byte[] buf,int length,netAddress address,int port);
<3>获取内容:getData();
<4>设置内容:setData(byte[] buf);
<5>获取长度:getLength();
②DatagramSocket
用来发送和接收数据报包的套接字;
可以实现给予UDP协议进行通信,可以发送或者接收对应的数据报包;
<1>构造函数:DatagramSocket(int port);
<2>接收数据报包:receive(DatagramPacket p);
<3>发送数据报包:send(DatagramPacket p);
<4>关闭:close();
UDP开发步骤:
<1>实例化套接字对象;
<2>实例化数据报包 接收报包和发送报包;
<3>发送或接收内容;
<4>关闭销毁;
class TalkServer{
//UDP协议
//接收消息
public static void main(String[] args) throws IOException {
//实例化套接字对象 参数为端口号
DatagramSocket datagramSocket = new DatagramSocket(8881);
//实例化数据报包 用于消息的接收
//创建byte字节数组
byte[] arr = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(arr,arr.length);
//接收消息
datagramSocket.receive(datagramPacket);
//显示信息
System.out.println("接收消息:"+new String(datagramPacket.getData(),0,datagramPacket.getLength()));
//关闭
datagramSocket.close();
}
}
class TaleClient{
//客户端
public static void main(String[] args) throws IOException {
//实例化套接字对象
DatagramSocket socket = new DatagramSocket(8882);
//实例化 发送数据的数据包
//创建byte数组
byte[] arr = "内涵段子".getBytes();
DatagramPacket datagramPacket = new DatagramPacket(arr,arr.length,InetAddress.getLocalHost(),8881);
//发送消息
socket.send(datagramPacket);
//关闭
socket.close();
}
}
基于UDP协议实现网络聊天室
class TalkServer{
//基于UDP协议实现网络聊天室
//转发服务器
public static void main(String[] args) throws IOException {
//创建套接字
DatagramSocket socket = new DatagramSocket(10010);
//准备集合 记录 在线的地址信息 记录端口号
HashSet<Integer> hashSet = new HashSet<>();
//准备发送和接收的字节数组
byte[] sarr = new byte[1024];
byte[] rarr = new byte[1024];
//实例化 数据报包
DatagramPacket sdata = new DatagramPacket(sarr,sarr.length);
DatagramPacket rdata = new DatagramPacket(rarr,rarr.length);
String message;
System.out.println("聊天室");
//循环 接收和转发消息
while(true){
//接收消息
socket.receive(rdata);
//获取接收到的消息
//校验当前客户端是否已经记录
if(!hashSet.contains(rdata.getPort())){
hashSet.add(rdata.getPort());
}
//获取接收的消息
message = new String(rarr,0,rdata.getLength());
System.out.println("聊天室:"+message);
//转发消息 其他人 不包含发消息的人
for(Integer port:hashSet){
sdata.setAddress(InetAddress.getLocalHost());
sdata.setPort(port);
sdata.setData(message.getBytes());
socket.send(sdata);
}
}
}
}
class TaleClient{
//客户端
public static void main(String[] args) throws IOException {
//创建套接字
DatagramSocket socket = new DatagramSocket(10010);
//线程池 多线程进行聊天 1个线程负责发送消息 1个负责接收消息
ThreadPoolExecutor tpe = new ThreadPoolExecutor(2,4,10, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(10));
//发送线程
tpe.execute(new Runnable() {
@Override
public void run() {
//数据报包
byte[] arr = new byte[1024];
DatagramPacket sdata;
try {
sdata = new DatagramPacket(arr,arr.length,InetAddress.getLocalHost(),10010);
String m;
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("我说:");
m=scanner.nextLine();
//设置发送消息
sdata.setData(m.getBytes("UTF-8"));
//发送消息
socket.send(sdata);
}
} catch (UnknownHostException | UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
//接收线程
tpe.execute(new Runnable() {
@SneakyThrows
@Override
public void run() {
//实例化数据报包
byte[] arr = new byte[1024];
DatagramPacket rdata = new DatagramPacket(arr,arr.length);
while(true){
//接收消息
socket.receive(rdata);
System.out.println("别人说:"+new String(arr,0,rdata.getLength()));
}
}
});
}
}
class TalkClient02{
//聊天室客户端02
public static void main(String[] args) throws SocketException {
//实例化套接字
DatagramSocket socket = new DatagramSocket(9002);
//线程池 多线程进行聊天 1个线程负责发送消息 1个负责接收消息
ThreadPoolExecutor tpe = new ThreadPoolExecutor(2,4,10,TimeUnit.SECONDS,new ArrayBlockingQueue<>(10));
//发送线程
tpe.execute(new Runnable() {
@SneakyThrows
@Override
public void run() {
//数据报包
byte[] arr = new byte[1024];
DatagramPacket sdata;
sdata = new DatagramPacket(arr,arr.length,InetAddress.getLocalHost(),10010)
String m;
Scanner scanner = new Scanner(System.in);
while(true){
System.out.println("我说:");
m=scanner.nextLine();
//设置发送消息
sdata.setData(m.getBytes("Utf-8"));
//发送消息
socket.send(sdata);
}
}
});
//接收线程
tpe.execute(new Runnable() {
@Override
public void run() {
byte[] arr = new byte[1024];
DatagramPacket rdata = new DatagramPacket(arr,arr.length);
while(true){
//接收消息
try {
socket.receive(rdata);
System.out.println("别人说"+new String(arr,0,rdata.getLength()));
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
}