Java—springboot实现UDP监听
1、监听类(需要创建两个线程)
package com.roc.springbootudp.config;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.logging.Logger;
/**
* @Author zwp
* @Date 2021/12/15 19:30
**/
@WebListener
public class UDPListener implements ServletContextListener
{
public static Logger logger = Logger.getLogger(UDPListener.class.getName());
public static final int MAX_UDP_DATA_SIZE = 4096;
public static final int UDP_PORT = 8899;
public static DatagramSocket socket = null;
@Override
public void contextInitialized(ServletContextEvent sce)
{
logger.info("========启动一个线程,监听UDP数据报。PORT:" + UDP_PORT + "=========");
try
{
// 启动一个线程,监听UDP数据报
new Thread(new ReceiveProcess(UDP_PORT)).start();
} catch (SocketException e)
{
e.printStackTrace();
}
}
class ReceiveProcess implements Runnable
{
ReceiveProcess(int port) throws SocketException
{
//创建服务器端DatagramSocket,指定端口
socket = new DatagramSocket(port);
}
@Override
public void run()
{
logger.info("=======创建数据报,用于接收客户端发送的数据======");
while (true)
{
byte[] buffer = new byte[MAX_UDP_DATA_SIZE];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
try
{
logger.info("=======此方法在接收到数据报之前会一直阻塞======");
socket.receive(packet);
logger.info("=======接收到的UDP信息======");
buffer = packet.getData();// 接收到的UDP信息,然后解码
String srt = new String(buffer, "UTF-8").trim();
logger.info("=======Process srt UTF-8======" + srt);
// 启动新的线程用于发送数据
new Thread(new SendProcess(packet)).start();
logger.info("=======发送数据的新线程已经启动======");
} catch (IOException e)
{
e.printStackTrace();
}
}
}
}
class SendProcess implements Runnable
{
DatagramPacket packet;
SendProcess(DatagramPacket packet)
{
this.packet = packet;
}
@Override
public void run()
{
logger.info("====过程运行=====");
try
{
logger.info("====向客户端响应数据=====");
//1.定义客户端的地址、端口号、数据
InetAddress address = packet.getAddress();
int port = packet.getPort();
byte[] data = "{'request':'alive','code':'0'}".getBytes();
//2.创建数据报,包含响应的数据信息
packet = new DatagramPacket(data, data.length, address, port);
//3.响应客户端
socket.send(packet);
logger.info("====数据发送成功!=====");
} catch (Exception e)
{
e.printStackTrace();
}
}
}
@Override
public void contextDestroyed(ServletContextEvent sce)
{
logger.info("========UDPListener摧毁=========");
}
}
2、配置启动项目时启动监听的注解@ServletComponentScan
package com.roc.springbootudp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan
public class SpringbootUdpApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootUdpApplication.class, args);
}
}
3、发送测试数据(当前时间)
package com.roc.springbootudp.test;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Date;
/**
* @Author zwp
* @Date 2021/12/15 19:35
**/
public class test {
public static final String SERVER_HOSTNAME = "localhost";
// 服务器端口
public static final int SERVER_PORT = 8899;
// 本地发送端口
public static final int LOCAL_PORT = 8888;
public static void main(String[] args) {
try {
// 1,创建udp服务。通过DatagramSocket对象。
DatagramSocket socket = new DatagramSocket(LOCAL_PORT);
// 2,确定数据,并封装成数据包。DatagramPacket(byte[] buf, int length, InetAddress address, int port)
Date data= new Date();
byte[] buf = data.toString().getBytes();
DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName(SERVER_HOSTNAME),
SERVER_PORT);
// 3,通过socket服务,将已有的数据包发送出去。通过send方法。
socket.send(dp);
// 4,关闭资源。
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}