我是套接字编程的新手,当遇到障碍时,我正在研究一些临时代码以使其感觉更好。任何关于我做错事情的指导将不胜感激!
我正在尝试编写一个简单的程序,该程序绑定并侦听用户指定的端口,并向任何连接发送“ Hello”消息。对于踢,我想我只会在同一端口上侦听所有IPv4和IPv6地址。这是一个代码片段:
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if ( getaddrinfo(NULL, argv[1], &hints, &res) != 0 ) {
printf("getaddrinfo failed!\n");
return 1;
}
for ( addrinfo* p = res; p != NULL; p = p->ai_next ) {
inet_ntop(p->ai_family, get_addr_ptr(p->ai_addr), ipstr, sizeof ipstr);
printf("Found IP: %s\n",ipstr);
printf("\tGetting socket...\t");
sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if ( sockfd == -1 ) {
perror("\t\tError");
continue;
}
printf("OK\n");
printf("\tBind Socket to Port...\t");
if ( bind(sockfd, p->ai_addr, p->ai_addrlen) == -1 ) {
perror("\t\tError");
close(sockfd);
continue;
}
printf("OK\n");
printf("\tListen on socket...\t");
if ( listen(sockfd, BACKLOG) == -1 ){
perror("\t\tError");
continue;
}
printf("OK\n");
}
freeaddrinfo(res);
while (1) {/* accept connections */}
运行代码时,得到以下输出:
$ ./simpleServer 8080
Found IP: 0.0.0.0
Getting socket... OK
Bind Socket to Port... OK
Listen on socket... OK
Found IP: ::
Getting socket... OK
Bind Socket to Port...
Error: Address already in use
但是,如果我查看netstat
程序何时运行,则看不到与绑定的任何冲突端口::
,或与此相关的任何其他IPv6地址。
我对此进行了更多研究,发现我可以仅使用IPv4或仅使用IPv6绑定到端口,但不能同时绑定这两个,我不理解。我创建了两个套接字,其中包含以下ai_addr:
AF_INET
地址信息:0.0.0.0:8008
AF_INET6
地址信息::::8080
我觉得我可能缺少一些基本知识,但我看不到。
谢谢!
您面临的问题可能是您正在使用双栈模式。至少在Linux(其他有经常禁用例如FreeBSD)指定::
的地址单产结合*
作为netstat
或ss
会把它。这意味着它接受IPv6和IPv4地址。尽管IPv4映射到::ffff:<your normal ipv4 address>
。所以我想您也遇到了同样的问题。
IPV6_V6ONLY
如果af_family == AF_INET6
不允许这种行为,则可以使用套接字选项。
IPV6_V6ONLY(从Linux 2.4.21和2.6开始)如果此标志设置为true(非零),则套接字被限制为仅发送和接收IPv6数据包。在这种情况下,IPv4和IPv6应用程序可以同时绑定到单个端口。如果此标志设置为false(零),则套接字可用于与IPv6地址或映射了IPv4的IPv6地址之间收发数据包。
参数是一个指向整数的布尔值的指针。
此标志的默认值由文件/ proc / sys / net / ipv6 / bindv6only的内容定义。该文件的默认值为0(假)。
取自男子7 ipv6
请注意,您正在覆盖以前创建/绑定/监听的套接字。也可用于gai_strerror
从返回值获得有意义的错误getaddrinfo
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句