SpringBoot中使用UDP监听端口获取数据

需求:在springboot项目启动后,另开启一个线程来监听某个端口发送的udp包数据,并且实时将获取到的数据入库。

1.可以先下载一个TCP/UDP Socket调试工具。

因为udp没有response,所以先确定用工具能接收到udp包数据,创建udp server来监听某个端口,创建udp client给指定ip和端口发数据包,联调时候先用此工具看看能否接收到外部发送到本地的udp数据包。

2.如果确定上述工具可以接收到目标数据包,那么可以开始用代码实现了,直接复制即可使用,其中在这里我们开启了一个线程监听发送到本地9072端口的udp数据包。

package com.genew.nms.utils.WebSocket;

import com.genew.nms.bean.BulkCallRecord;
import com.genew.nms.service.bulkcalltask.IBulkCallRecordService;
import com.genew.nms.utils.ApplicationContextUtil;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.time.LocalDateTime;
import java.time.ZoneOffset;


/**
 * @author Salong
 * @date 2022/5/25 11:02
 * @Email:salong0503@aliyun.com
 */

@Slf4j
@WebListener
public class UdpClient implements ServletContextListener {


    public static final int MAX_UDP_DATA_SIZE = 4096;
    public static final int UDP_PORT = 9072;
    public static DatagramPacket packet = null;
    public static DatagramSocket socket = null;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        try {
            log.info("Start thread to listen to UDP(port:{}) data!" , UDP_PORT );
            // 启动一个线程,监听UDP数据报
            new Thread(new UDPProcess(UDP_PORT)).start();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    class UDPProcess implements Runnable {
        public UDPProcess(final int port) throws SocketException {
            //创建服务器端DatagramSocket,指定端口
            socket = new DatagramSocket(port);
        }

        @Override
        public void run() {
            while (true) {
                byte[] buffer = new byte[MAX_UDP_DATA_SIZE];
                packet = new DatagramPacket(buffer, buffer.length);
                try {
                    log.info("waiting udp data!");
                    socket.receive(packet);
                    new Thread(new Process(packet)).start();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }

    class Process implements Runnable {
        public Process(DatagramPacket packet) throws UnsupportedEncodingException {
            // 接收到的UDP信息,然后解码
            byte[] buffer = packet.getData();
            String data = new String(buffer, "UTF-8").trim();
            log.info("UDP Received Data:{}", data);
        }

        @Override
        public void run() {
            try {
                log.info("Start UDP Response.");
                //1.定义客户端的地址、端口号、数据
                InetAddress address = packet.getAddress();
                int port = packet.getPort();
                byte[] data2 = "{'request':'alive','errcode':'0'}".getBytes();
                //2.创建数据报,包含响应的数据信息
                DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);
                //3.响应客户端
                socket.send(packet2);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("UDPListener destroyed!");
    }

   

}

3.使用工具发送请求到本地9072端口。

4.获取数据封装入库

为什么写这一层,是因为在实际开发中可能需要注入某一个service来将数据入库,但新建线程中是无法直接使用autowired来注入service的,所以后续的操作是来解决这方面的问题的。如果没有此需要,可以直接跳过。

直接复制下面代码到项目。

package com.genew.nms.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * @author Salong
 * @date 2022/5/26 14:35
 * @Email:salong0503@aliyun.com
 */
@Component
public class ApplicationContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextUtil.applicationContext = applicationContext;
    }

    public static Object getBeanByName(String beanName) {
        if (applicationContext == null) {
            return null;
        }
        return applicationContext.getBean(beanName);
    }

    public static <T> T getBean(Class<T> type) {
        return applicationContext.getBean(type);
    }
}

 然后在类中取消使用autowired来注入sevice,使用下面的方式来获取service对象。

IBulkCallRecordService recordService = ApplicationContextUtil.getBean(IBulkCallRecordService.class);

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

却诚Salong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值