参考博客:https://www.cnblogs.com/zhaozihan/archive/2016/11/12/6057118.html
客户端类:
public class UDPClient {
public static void main(String[] args) throws IOException{
//定义服务器的地址,端口号,数据
InetAddress address=InetAddress.getByName("localhost");
int port=8800;
byte[] data="张三李四王五赵六".getBytes();//将字符串转换为字节数组
//创建数据报
DatagramPacket packet=new DatagramPacket(data,data.length,address,port);
//创建DatagramSocket,实现数据发送和接收
DatagramSocket socket=new DatagramSocket();
//向服务器端发送数据报
socket.send(packet);
//接收服务器端响应的数据
byte[] data2=new byte[1024];
DatagramPacket packet2=new DatagramPacket(data2,data.length);
socket.receive(packet2);
String info=new String(data2,0,packet2.getLength());
System.out.println("我是客户端,服务器说:"+info);
socket.close();
}
}
服务器端类:
public class UDPserver {
public static void main(String[] args) throws IOException{
DatagramSocket socket = new DatagramSocket(8800);
DatagramPacket packet=null;
byte[] data=null;
int count = 0;
System.out.println("服务器端启动,等待发送数据");
while(true){
data=new byte[1024];//创建字节数组,指定接收数据报的大小
packet=new DatagramPacket(data,data.length);
socket.receive(packet);//此方法接收到数据报之前会一直阻塞
Thread thread=new Thread(new UDPServerThread(socket,packet));
thread.start();
count++;
System.out.println("服务器被连接过的次数:"+count);
InetAddress address=packet.getAddress();
System.out.println("当前客户端的IP为:"+address.getHostAddress());
}
}
}
服务器端线程处理类
public class UDPServerThread implements Runnable{
/*
发送
1、获取数据报套接字连接
2、定义数据报包
3、通过该连接发送数据报包
获取
1、获取发送过来的数据报包
2、获取数据报包中的数据
byte[]与String类型的转换
public String(byte[] bytes) 使用byte数组构件一个String
public byte[] getBytes(String charsetName) 使用指定的字符集将此String编码为byte数列
这两个均为String对象的方法
*/
DatagramSocket socket=null;//用来表示发送和接收数据包的套接字 即数据报套接字
/*
在DatahgramSocket上总是启用UDP广播发送
DatagramSocket s=new DatagramSocket(null);
s.bind(new InetSocketAddress(8888));
DatagramSocket s=new DatagramSocket(8888);
这两种实现的效果一致
*/
DatagramPacket packet=null;//用来表示数据报包
/*
数据报包用来实现无连接包投递服务。每条报文仅根据该包中所包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可选择不同的路由,
也可按照不容的顺序到达,不对包投递做出保证 由此可以看出 DatagramPacket是专门供无连接的UDP使用的
*/
public UDPServerThread(DatagramSocket socket,DatagramPacket packet){
this.socket=socket;
this.packet=packet;
}
public void run(){
String info=null;
InetAddress address=null;
int port=8800;
byte[] data2=null;
DatagramPacket packet2=null;
try{
/*
public byte[] getData() 返回用来接收和发送数据的缓冲区
public int getLength()返回要发送和接收到的数据长度
public void setData(byte[] buf,int offset,int length) 为此包设置数据缓冲区,此方法设置包的数据、长度和偏移量
*/
info=new String(packet.getData(),0,packet.getLength());
System.out.println("我是服务器,客户端说"+info);
address=packet.getAddress();//获取该包是从哪台机器发送过来的
port=packet.getPort();//获取该包是从哪个端口发送过来的
data2="我在响应你!".getBytes();
/*
DatagramPacket(byte[] buf,int length,InetAddress address,int port)
构造数据报包,将长度为length的包发送到指定主机的指定端口号
*/
packet2=new DatagramPacket(data2,data2.length,address,port);
socket.send(packet2);//从此套接字发送数据报包
}catch(IOException e){
e.printStackTrace();
}
//socket.close();//不能关闭 因为要一直读取客户端的连接
}
}