You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Integration UDP示例无回复致客户端挂起,如何实现应答?

在Spring Boot UDP服务中实现客户端回复

要解决客户端发送UDP消息后挂起的问题,核心是让服务端收到消息后向客户端返回确认回复。以下是具体实现步骤:

1. 修改UDP服务配置

将原有的单向接收适配器替换为支持回复的Spring Integration UDP入站适配器,它会自动将客户端地址信息携带到消息头中:

package com.wheresjim.udp.config

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.integration.dsl.IntegrationFlow
import org.springframework.integration.dsl.Udp

@Configuration
class UdpConfig {

    private Integer port = 6767

    @Bean
    IntegrationFlow processUdpMessage() {
        IntegrationFlow
                .from(Udp.inboundAdapter(port))
                .handle("udpService", "receive")
                .get()
    }
}

2. 修改消息处理器,返回回复内容

修改UdpService的receive方法,使其返回回复消息,并保留原消息头中的客户端地址信息,Spring Integration会自动将回复发送回客户端:

package com.wheresjim.udp.service

import org.springframework.messaging.Message
import org.springframework.messaging.support.MessageBuilder
import org.springframework.stereotype.Component

@Component
class UdpService {

    Message<String> receive(Message<byte[]> message) {
        // 解析收到的UDP消息内容
        String data = new String(message.getPayload())
        System.out.println("收到客户端消息:" + data)
        
        // 构造自定义回复内容
        String replyContent = "确认收到:" + data
        
        // 复制原消息头(包含客户端地址/端口),构造回复消息
        return MessageBuilder.withPayload(replyContent)
                .copyHeaders(message.getHeaders())
                .build()
    }
}

3. 客户端代码优化(可选)

调整客户端代码,支持多次发送消息,并正确处理回复:

DatagramSocket socket = new DatagramSocket()
InetAddress address =  InetAddress.getByName('localhost')

String sendUDP(String msg, InetAddress address, DatagramSocket socket) {
    byte[] buf = msg.getBytes()
    println "发送消息字节长度:" + buf.length
    
    // 发送消息到服务端
    DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 6767)
    socket.send(packet)
    
    // 接收服务端回复
    byte[] receiveBuf = new byte[1024]
    DatagramPacket receivePacket = new DatagramPacket(receiveBuf, receiveBuf.length)
    socket.receive(receivePacket)
    
    String received = new String(receivePacket.getData(), 0, receivePacket.getLength())
    println "收到服务端回复:" + received
    return received
}

String testMsg = '<?xml version="1.0" encoding="UTF-8"?><TestMsg><Text>Hello World</Text></TestMsg>'

// 测试发送多条消息
try {
    for (int i = 0; i < 3; i++) {
        sendUDP(testMsg + " (第" + (i+1) + "次发送)", address, socket)
        Thread.sleep(1000)
    }
} catch (Exception e) {
    e.printStackTrace()
} finally {
    socket.close()
}

关键原理说明

  • Udp.inboundAdapter()会自动在收到的消息头中添加ip_remoteAddress(客户端地址)和ip_remotePort(客户端端口)属性。
  • 当处理器返回消息时,Spring Integration会读取这些头信息,自动将回复发送回对应的客户端地址,无需手动配置发送适配器。
  • UDP是无连接协议,必须依赖每次消息携带的客户端地址完成回复,无法复用固定连接。

内容的提问来源于stack exchange,提问作者Jim Gough

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 16:10:37