我编写了一个只绑定到指定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,Darwin内核版本12.4.0 X86_64
答案 0 :(得分:1)
名称绑定中使用的规则因地址系列而异。并且在struct sockaddr_in中也有这个sin_zero字段,有些人声称必须将其设置为零。其他人对它没有任何要求(Linux文档根本没有提到它),还有其他文档声称sin_zero已从struct sockaddr_in中删除, 我试过用bzero评论和未评论。评论在本地网络中运行良好,但未评论的版本无论是否在本地网络中都有效。所以我猜bzeroing是一种很好的做法。