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

使用sendmsg/recvmsg系统调用实现UDP通信时报Invalid argument错误

问题根源分析

你遇到的Invalid argument错误核心来自客户端msghdr结构体参数配置错误,同时服务端也存在参数赋值逻辑问题,具体错误点如下:

1. 客户端错误点

  • msg.msg_name配置错误:msghdr的msg_name字段要求传入对端socket地址结构体的指针,你错误传入了字符串格式的IP地址argv[2],正确应该传入你提前初始化好的struct sockaddr_in server的地址。
  • msg.msg_namelen配置错误:该字段要求传入地址结构体的长度,你错误用了sizeof(inet_addr(argv[2])),实际值应该是sizeof(struct sockaddr_in)。
  • (非报错优化项)iovec.iov_len你填了整个buffer的长度512,实际你从标准输入只读取了c个字节,可修改为c避免发送无效数据。

2. 服务端错误点

  • 结构体赋值顺序错误:你先给msg.msg_name、msg.msg_namelen赋值,之后才执行memset(&msg, 0, sizeof(msg)),之前的赋值会被清空,完全无效。
  • 如果你需要获取客户端地址,需要将msg.msg_name指向你定义的client结构体地址,同时msg.msg_namelen设置为sizeof(client);如果不需要获取对端地址,保持msg.msg_name为NULL也可以正常接收数据。
修正后的关键代码片段

客户端sendmsg部分修正

//sending to server
struct iovec i;
i.iov_base = buffer;
i.iov_len = c; // 改为实际读取的字节数

struct msghdr msg;
memset(&msg, 0, sizeof(msg));
msg.msg_name = &server; // 传入正确的地址结构体指针
msg.msg_namelen = sizeof(server); // 传入结构体实际长度
msg.msg_iovlen = 1;
msg.msg_iov = &i;
message_length = sendmsg(sock, &msg, 0);

服务端recvmsg部分修正(可选,适用于需要获取客户端地址的场景)

//receiving from client
struct iovec iv;
iv.iov_base = buffer;
iv.iov_len = sizeof(buffer);

struct msghdr msg;
memset(&msg, 0, sizeof(msg)); // 先清空结构体再赋值
msg.msg_name = &client; // 指向存放客户端地址的结构体
msg.msg_namelen = sizeof(client);
msg.msg_iovlen = 1;
msg.msg_iov = &iv;
message_length = recvmsg(sockmain, &msg, 0);
// 打印前补充字符串结束符,避免脏数据
buffer[message_length] = '\0';
额外优化建议
  • 客户端UDP可以不用主动bind,操作系统会自动分配临时端口,你现有代码里的bind逻辑不是错误,但属于冗余代码可直接删除。
  • 建议替换已被标记为过时的inet_addr接口,改用inet_pton兼容性更强。

内容的提问来源于stack exchange,提问作者Teja Puvvula

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 09:51:00