我在以下场景中遇到IGMP套接字调用错误;
fd = socket(PF_INET, SOCK_RAW, IPPROTO_IGMP) ;
setsockopt( fd, IPPROTO_IP, IP_HDRINCL, nval, sizeof(nval) );
/** Fill in the IP header and Ethernet header**/
/*** Fill, create the IGMP packet structures***/
if(sendto( fd, &buf, sizeof(buf), 0,(struct sockaddr *) &addr, sizeof(addr)) < 0) {
printf("Socket Sendto error %d : %s\n", errno, strerror(errno));
return 0;
}
sendto调用失败,说消息太长。 我使用8192作为缓冲区大小。所以我尝试使用以下调用来修复此错误;
if(setsockopt(dlpifd, IPPROTO_IP, SO_SNDBUF, &val, sizeof(int)) < 0) {
printf("Can't set socket options:%d:%s\n", errno, strerror(errno));
return 0;`
}
setsockopt()调用成功,但sendto();
的错误相同所以我用getsockopt()调用检查SO_SNDBUF大小,它显示1个字节?!
我在做什么。
Linux内核是否需要重新编译才能获得IGMP支持?或者我错过了什么?
答案 0 :(得分:7)
Ethernet(您最可能使用的链接层)帧通常为1500字节长。为send()
提供消息的确切大小,而不是缓冲区大小。
SO_SNDBUF
是内核中的每个套接字缓冲区,它告诉TCP缓冲多少,限制UDP数据报的大小,对原始套接字没有任何意义。