Springboot启动Udp监听服务,创建socket,接收数据包

使用@WebListener注解
创建一个监听器继承ServletContextListener类
自动重写ServletContextListener中的contextInitialized(),contextDestroyed()两个方法。

contextInitialized()启动时的方法内容。
contextDestroyed()关闭服务时的方法内容。

代码如下:

import com.xxx.xxx.config.ThreadPoolConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

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.SocketException;
import java.nio.charset.StandardCharsets;

@Component
@WebListener
@ConfigurationProperties(prefix = "xxxx.udp")
public class HmpsOrionUdpListener implements ServletContextListener {
    private static Logger logger = LoggerFactory.getLogger(HmpsOrionUdpListener.class);

    private static int udpPort;
    private static int maxUdpDataSize;
    private ThreadPoolConfig threadPoolConfig = new ThreadPoolConfig();


    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        logger.info("========> 启动一个线程,监听UDP数据包,监听端口 {} <======== ", udpPort);
        // 启动一个线程,监听UDP数据报
        threadPoolConfig.threadPoolTaskExecutor().execute(() -> {
            try {
                execteUdpMsg(udpPort);
            } catch (SocketException e) {
                logger.error(e.getMessage());
            }
        });
    }

    private void execteUdpMsg(int port) throws SocketException {

        //创建服务器端DatagramSocket,指定端口
        DatagramSocket socket = new DatagramSocket(port);

        logger.info("=======创建数据报,用于接收客户端发送的数据======");
        while (true) {
            byte[] buffer = new byte[maxUdpDataSize];
            DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
            try {
                logger.info("=======端口 {} 等待接收消息 ======", udpPort);
                socket.receive(packet);
                // 接收到的UDP信息,然后解码
                buffer = packet.getData();
                String srt2 = new String(buffer, StandardCharsets.UTF_8).trim();
                logger.info("=======端口 {} 接收接收消息 {} ======", srt2);
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
    }


    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        logger.info("========> 关闭监听UDP数据包,监听端口 {} <======== ", udpPort);
    }

    public static int getUdpPort() {
        return udpPort;
    }

    public static void setUdpPort(int udpPort) {
        HmpsOrionUdpListener.udpPort = udpPort;
    }

    public static int getMaxUdpDataSize() {
        return maxUdpDataSize;
    }

    public static void setMaxUdpDataSize(int maxUdpDataSize) {
        HmpsOrionUdpListener.maxUdpDataSize = maxUdpDataSize;
    }
}

test一下

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class test {
    private static final String SERVER_HOSTNAME = "127.0.0.1";
    // 服务器端口
    private static final int SERVER_PORT = 6007;
    // 本地发送端口
    private 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)
            byte[] buf = "你好,世界".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();
        }
    }
}


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * 线程池配置
 *
 * @author ruoyi
 **/
@Configuration
public class ThreadPoolConfig
{
    // 核心线程池大小
    private int corePoolSize = 50;

    // 最大可创建的线程数
    private int maxPoolSize = 200;

    // 队列最大长度
    private int queueCapacity = 1000;

    // 线程池维护线程所允许的空闲时间
    private int keepAliveSeconds = 300;

    @Bean(name = "threadPoolTaskExecutor")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor()
    {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.initialize();
        executor.setMaxPoolSize(maxPoolSize);
        executor.setCorePoolSize(corePoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(keepAliveSeconds);
        // 线程池对拒绝任务(无线程可用)的处理策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
}

xxxx:
  udp:
    udp_port: 6007
    max_udp_data_size: 4096

socket.receive(packet);方法会阻塞
阻塞等待其他socket发从包到本服务器端口,在进行数据的获取

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值