【问题标题】:Socket error:90:Message Too Long套接字错误:90:消息太长
【发布时间】:2011-06-15 07:28:42
【问题描述】:

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 支持?还是我错过了什么?

【问题讨论】:

    标签: c sockets network-programming linux-kernel igmp


    【解决方案1】:

    Ethernet(您最有可能使用的链路层)帧通常为 1500 字节长。为send() 提供消息的确切大小,而不是缓冲区大小。

    SO_SNDBUF 是内核中的每个套接字缓冲区,它告诉 TCP 缓冲多少,限制 UDP 数据报的大小,并且对原始套接字没有任何意义。

    【讨论】:

    • 谢谢尼克!寻求帮助。这是否意味着对于这种情况我应该使用 send() 而不是 sendto() 和确切的消息大小(即使它超过 1500 默认大小?!)而不是 buff 大小。
    • 嗨,我正在尝试发送 IGMP 数据包 'pigmp->igmp_type = IGMP_MEMBERSHIP_QUERY;'而不是 TCP 或 UDP,我怀疑我在代码中执行的调用/操作顺序可能是错误的,或者我用于填充结构的参数/值应该是错误的。我查了一下,没有发现这些方面的毛病。所以使用 send() 代替 sendto() 并不能解决这个问题。任何从事 IGMP(多播)工作的人都可以给我一些启发。 -提前致谢 -Sathya
    • 嗨 Nik,如前所述,现在它适用于数据包大小
    • sendto() 很好——我还是用send() 作为通用名称。您不会通过以太网获得大于 1500 字节的任何内容 - 这是硬件限制。 SO_SNDBUF 在这里不起作用 - 原始套接字不做缓冲。
    猜你喜欢
    • 1970-01-01
    • 2021-03-21
    • 2017-11-23
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    • 2020-07-03
    • 2022-01-19
    • 2013-09-04
    相关资源
    最近更新 更多