2

我编写了一个小套接字程序,它只绑定到指定的 ip:port,但如果 struct sockaddr_in 不是 bzero 并且 gcc 带有选项 -O2,则 bind() 失败。

这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>

int main(int argc, char **argv){
    struct sockaddr_in addr;
    //bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons((unsigned short)9009);
    inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);

    int sock;
    if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1){
        perror("socket error");
        exit(0);
    }   
    if(bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1){
        printf("socket error: %d, %s\n", errno, strerror(errno));
        exit(0);
    }   

    return 0;
}

请注意bzero(&addr, sizeof(addr));被注释掉,我打算由每个成员初始化 sockadd_in。编译并运行:

$ gcc a.c; ./a.out
OK

$ gcc -O2 a.c; ./a.out 
socket error: 49, Can't assign requested address

我们可以知道 struct sockadd_in 定义为:

struct in_addr {
  in_addr_t   s_addr;           /* 32-bit IPv4 address */
                                /* network byte ordered */
};

struct sockaddr_in {
  uint8_t         sin_len;      /* length of structure (16) */
  sa_family_t     sin_family;   /* AF_INET */
  in_port_t       sin_port;     /* 16-bit TCP or UDP port number */
                                /* network byte ordered */
  struct in_addr  sin_addr;     /* 32-bit IPv4 address */
                                /* network byte ordered */
  char            sin_zero[8];  /* unused */
};

我的问题是, bind() 实现是否依赖于 sockaddr_in.sin_zero 被清除?

编辑:Mac OS X,达尔文内核版本 12.4.0 X86_64

4

1 回答 1

1

The rules used in name binding vary between address families. and there's also this sin_zero field in struct sockaddr_in which some people claim must be set to zero. Other people don't claim anything about it (the Linux documentation doesn't even mention it at all), and there are other documentation which claim sin_zero has been removed from struct sockaddr_in, I have tried with both bzero commented and un-commented. The commented works good some time in a local network but un-commented version works all time either local network or not. so i guess bzeroing is good practice.

于 2013-09-17T05:45:13.950 回答