UDP特点
UDP是面向无连接的,传输数据不安全,效率较高。操作数据不能太大,数据太大可以分开发送
UDP编程套路
创建接收端
接收端
- 使用DatagramSocket 指定端口 创建接收端
- 准备容器 封装成DatagramPacket包裹
- 阻塞式接收包裹receive(DatagramPacket p)
- 分析数据 byte[] getData() 获取数据 int getLength()获取数据长度
- 释放资源
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UdpServer {
public static void main(String[] args) throws Exception {
System.out.println("----接收方启动中-----");
//1.使用DatagramSocket 指定端口 创建接收端
DatagramSocket server=new DatagramSocket(999);
//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();
}
}
创建发送端
发送端
- 使用DatagramSocket 指定端口 创建发送端
- 准备数据一定转成字节数组
- 封装成DatagramPacket包裹,需要指定目的地
- 发送包裹send(DatagramPacket p)
- 释放资源
import java.net.*;
public class UdpClient {
public static void main(String[] args) throws Exception {
System.out.println("----发送方启动中-----");
//1.使用DatagramSocket 指定端口 创建发送端
DatagramSocket client=new DatagramSocket(8888);
// 2.准备数据一定转成字节数组
String data="我一定可以";
byte[] datas=data.getBytes();
// 3.封装成DatagramPacket包裹,需要指定目的地
//传入参数为 (数据集,数据初始位置即0,数据长度,接收端对象(接收端地址,接收端端口))
DatagramPacket packet=new DatagramPacket(datas,0,datas.length,
new InetSocketAddress("localhost",999));
// 4.发送包裹send(DatagramPacket p)
client.send(packet);
// 5.释放资源
client.close();
}
}
UDP编程操作基本数据类型
接收端
基本数据类型接收端
- 使用DatagramSocket 指定端口 创建接收端
- 准备容器 封装成DatagramPacket包裹
- 阻塞式接收包裹receive(DatagramPacket p)
- 分析数据 将字节数组还原为原来的数据类型(采用io)
DataInputStream dis=new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(获取到的数据))); - 释放资源
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UdpTypeServer {
public static void main(String[] args) throws Exception {
System.out.println("----接收方启动中-----");
//1.使用DatagramSocket 指定端口 创建接收端
DatagramSocket server=new DatagramSocket(999);
//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);
System.out.println(age);
System.out.println(flag);
System.out.println(ch);
//5.释放资源
server.close();
}
}
发送端
基本数据类型发送端
- 使用DatagramSocket 指定端口 创建发送端
- 将基本数据类型转成字节数组
- 封装成DatagramPacket包裹,需要指定目的地
- 发送包裹send(DatagramPacket p)
- 释放资源
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
public class UdpTypeClient {
public static void main(String[] args) throws Exception {
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(10);
dos.writeBoolean(false);
dos.writeChar('a');
dos.flush();
byte[] datas=baos.toByteArray();
// 3.封装成DatagramPacket包裹,需要指定目的地
//传入参数为 (数据集,数据初始位置即0,数据长度,接收端对象(接收端地址,接收端端口))
DatagramPacket packet=new DatagramPacket(datas,0,datas.length,
new InetSocketAddress("localhost",999));
// 4.发送包裹send(DatagramPacket p)
client.send(packet);
// 5.释放资源
client.close();
}
}
实现多次发送和接收数据
接收端
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UdpTalkServer {
public static void main(String[] args) throws Exception {
System.out.println("----接收方启动中-----");
//1.使用DatagramSocket 指定端口 创建接收端
DatagramSocket server=new DatagramSocket(999);
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();
}
}
发送端
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
public class UdpTalkClient {
public static void main(String[] args) throws Exception {
System.out.println("----发送方启动中-----");
//1.使用DatagramSocket 指定端口 创建发送端
DatagramSocket client=new DatagramSocket(8888);
// 2.准备数据一定转成字节数组
//用户输入
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
System.out.println("当输入bye时结束");
while (true){
String data=reader.readLine();
byte[] datas=data.getBytes();
// 3.封装成DatagramPacket包裹,需要指定目的地
//传入参数为 (数据集,数据初始位置即0,数据长度,接收端对象(接收端地址,接收端端口))
DatagramPacket packet=new DatagramPacket(datas,0,datas.length,
new InetSocketAddress("localhost",999));
// 4.发送包裹send(DatagramPacket p)
client.send(packet);
if(data.equals("bye")){
break;
}
}
// 5.释放资源
client.close();
}
}
实现一个简单的双方交流功能
封装一个发送方法
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
public class TalkSend implements Runnable{
private DatagramSocket client;
private BufferedReader reader;
private String toIP;//对方的ip地址
private int toPort;//对方的端口
public TalkSend(int port,String toIP,int toPort){//传入端口
this.toIP=toIP;
this.toPort=toPort;
try {
client=new DatagramSocket(port);
reader=new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true) {
String data = null;
try {
data = reader.readLine();
byte[] datas=data.getBytes();
// 3.封装成DatagramPacket包裹,需要指定目的地
//传入参数为 (数据集,数据初始位置即0,数据长度,接收端对象(接收端地址,接收端端口))
DatagramPacket packet=new DatagramPacket(datas,0,datas.length,
new InetSocketAddress(this.toIP,this.toPort));
// 4.发送包裹send(DatagramPacket p)
client.send(packet);
if(data.equals("bye")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
封装一个接收方法
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
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){
//2.准备容器 封装成DatagramPacket包裹
byte[] container=new byte[1024*60];
DatagramPacket packet=new DatagramPacket(container,0,container.length);
//3.阻塞式接收包裹receive(DatagramPacket p)
try {
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(from+"说:"+data);
if(data.equals("bye")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
//5.释放资源
server.close();
}
}
创建两个聊天对象来运用发送和接收的方法进行双向交流
public class TalkStudent {
public static void main(String[] args) {
new Thread(new TalkSend(777,"localhost",999)).start();//发送
new Thread(new TalkReceive(888,"TalkTeacher")).start();//接收
}
}
public class TalkTeacher {
public static void main(String[] args) {
new Thread(new TalkReceive(999,"TalkStudent")).start();//接收
new Thread(new TalkSend(555,"localhost",888)).start();//发送
}
}