【问题标题】:setsockopt fails for IPPROTO_TCP IP_TOS in C对于 C 中的 IPPROTO_TCP IP_TOS,setsockopt 失败
【发布时间】:2011-09-02 17:51:09
【问题描述】:

我的代码失败了。我以 root 身份运行(与普通用户相同的行为)

首先我想设置 TOS,然后获取值。

int tos_local = 0x28;
if (setsockopt(sockfd, IPPROTO_TCP, IP_TOS,  &tos_local, sizeof(tos_local))) {
    error("error at socket option");
} else {
    int tos=0;
    int toslen=0;

    if (getsockopt(sockfd, IPPROTO_TCP, IP_TOS,  &tos, &toslen) < 0) {
            error("error to get option");
    }else {
            printf ("changing tos opt = %d\n",tos);
    }
}

printf 打印出来

更改为 opt = 0

我希望打印 0x28 (40)。

有什么问题?

正确答案:

    if (setsockopt(sockfd, **IPPROTO_IP**, IP_TOS,  &tos_local, sizeof(tos_local))) {

    int tos=0;
    int toslen=sizeof(tos); //that line here

    if (getsockopt(sockfd, IPPROTO_IP, IP_TOS,  &tos, &toslen) < 0) {

【问题讨论】:

  • getsockopt 的第 5 个参数是第 4 个参数指向的缓冲区的大小。因此,您需要删除示例代码中的 & 。或者更好的是,把 sizeof(tos) 放在那里,就像 Seth 说的那样。

标签: c linux sockets network-programming


【解决方案1】:

当调用getsockopt 时,你传入&tos 指向的内存大小。换句话说,将 toslen 初始化为 sizeof(tos)。

【讨论】:

  • 我得到编译器警告错误:警告:当我传递 sizeof(tos) 时,传递 getsockopt 的参数 5 使指针从整数而不进行强制转换。此外,getsockoption 因“错误地址”而失败
  • @cateof: 传递&amp;tos_len作为参数是正确的,但需要声明为int tos_len = sizeof (tos);而不是0
  • @cateof: @Ben Voight:我认为你的意思是,将 &tos_len 作为参数传递是正确的,但你需要将其初始化为 sizeof(tos) 而不是 0。
【解决方案2】:

IP_TOS 的级别为 IPPROTO_IP,而不是 IPPROTO_TCP

the documentation

这会影响设置和获取选项。

另外,Seth 所说的初始化长度参数,它只影响getsockopt

【讨论】:

  • 确实如此。并且 IP_TOS 恰好等于 1,TCP_NODELAY 也是如此,所以这段代码实际上做了一些事情......只是不是预期的。
  • @Nemo:是的,他们应该将这些设计为位域而不是单独的参数。但那是桥下的水。
猜你喜欢
  • 2013-07-06
  • 2012-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-20
  • 2012-08-20
相关资源
最近更新 更多