使用Raw Socket发送报文时sendto函数返回-1的问题求助
问题原因排查
- 地址类型不匹配:你创建的是
AF_PACKET类型的原始套接字,属于链路层套接字,对应的目标地址结构必须是struct sockaddr_ll,而你传入的是IPv4专用的struct sockaddr_in,类型完全不兼容,这是sendto返回-1的核心原因。 - 缺少运行权限:
AF_PACKET原始套接字需要root权限才能创建和操作,如果你用普通用户身份执行程序,连socket创建步骤都会失败,后续发送自然也会报错。 - 发送报文不符合要求:
AF_PACKETSOCK_RAW套接字要求用户自己构造完整的链路层报文(包括以太网帧头),你直接传入纯文本内容,没有合法的二层报文结构,内核也会拒绝发送。 - 缺少错误排查逻辑:你可以在
sendto调用失败后加一行perror("sendto error"),打印具体的错误原因,能快速定位问题类型。
修复方案参考
如果你的需求是发送普通IPv4报文,建议把套接字创建逻辑调整为适配IPv4的类型:
// 改成AF_INET的原始套接字,仅需要自行构造IP和上层协议头 int sock_r = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
如果确实需要操作链路层报文,就把目标地址改为struct sockaddr_ll类型,补全接口索引、目标MAC地址等参数,同时自行构造以太网头后再执行发送操作。
内容的提问来源于stack exchange,提问作者StwayneXG
相关产品推荐
相关产品推荐

