Golang TCP连接正常但UDP无法传输日志,求解决方法
问题:UDP日志传输无法被netcat监听到的原因及解决方法
现状描述
TCP场景工作正常:
监听命令:nc -lkp 1902
TCP代码:timeout := 30 * time.Second conn, err := net.DialTimeout("tcp", "localhost:1902", timeout) if err != nil { panic("Failed to connect to localhost:1902") } defer conn.Close() f := log.Ldate | log.Lshortfile logger := log.New(conn, "example-", f) logger.Println("This is a regular message1") logger.Println("This is a regular message2") logger.Println("This is a regular message3") logger.Println("This is a regular message4") logger.Println("This is a regular message5") logger.Println("This is a regular message6")输出结果:
example-2022/11/18 technique24.go:21: This is a regular message1 example-2022/11/18 technique24.go:22: This is a regular message2 example-2022/11/18 technique24.go:23: This is a regular message3 example-2022/11/18 technique24.go:24: This is a regular message4 example-2022/11/18 technique24.go:25: This is a regular message5 example-2022/11/18 technique24.go:26: This is a regular message6UDP场景无法工作:
UDP代码:timeout := 30 * time.Second conn, err := net.DialTimeout("udp", "localhost:1902", timeout) if err != nil { panic("Failed to connect to localhost:1902") } defer conn.Close() f := log.Ldate | log.Lshortfile logger := log.New(conn, "example-", f) logger.Println("This is a regular message1") logger.Println("This is a regular message2") logger.Println("This is a regular message3") logger.Println("This is a regular message4") logger.Println("This is a regular message5") logger.Println("This is a regular message6")问题:使用相同的
nc -lkp 1902监听时,接收不到任何UDP日志内容,需要解决UDP传输日志的问题以实现低积压的POC。
原因分析
- netcat监听模式不匹配:默认
nc -lkp 1902是监听TCP连接,UDP需要显式指定-u参数,否则nc不会处理UDP数据包,导致发送的内容被直接丢弃。 - UDP无连接特性:Go代码中的
DialTimeout只是绑定了UDP的目标地址,不会像TCP那样建立握手连接,所以即使监听端未开启UDP模式,Go程序也不会立刻抛出连接错误。
解决方法
步骤1:修改netcat监听命令
切换到UDP模式监听1902端口:
nc -ulkp 1902
参数说明:
-u:指定UDP协议模式-l:开启监听模式-k:保持持续监听(UDP下表示不处理完单个数据包就退出)-p:指定监听端口
步骤2:验证UDP传输
保持现有Go代码不变,运行程序后,UDP模式的nc监听端即可接收到日志内容。
额外优化建议
如果需要确认UDP数据包的发送状态,可以在代码中添加写操作的错误检查:
_, err = logger.Writer().Write([]byte("test message\n")) if err != nil { fmt.Printf("UDP写入错误: %v\n", err) }
内容的提问来源于stack exchange,提问作者Ameya Sinha
相关产品推荐
相关产品推荐

