IPv6:连接()总是与errno 22失败

操作系统是Ubuntu。 我正在做一个基本的IPv6操作的简单testing。 PC通过集线器与IP摄像机(支持IPv6)连接,ping6testing成功。

$ ping6 -I eth1 fe80::240:8cff:fe94:451e PING fe80::240:8cff:fe94:451e(fe80::240:8cff:fe94:451e) from fe80::224:8cff:fe90:ad3b eth1: 56 data bytes 64 bytes from fe80::240:8cff:fe94:451e: icmp_seq=1 ttl=64 time=3.86 ms 64 bytes from fe80::240:8cff:fe94:451e: icmp_seq=2 ttl=64 time=0.471 ms 

代码如下:

 #include <linux/in6.h> #include <sys/socket.h> #include <stdio.h> #include <errno.h> void main() { int s, ret, err; struct sockaddr_in6 addr; s = socket(AF_INET6, SOCK_STREAM, 0); addr.sin6_family = AF_INET6; addr.sin6_port = htons(554); addr.sin6_flowinfo = 0; addr.sin6_scope_id = 0; addr.sin6_addr.s6_addr[0] = 0xfe; addr.sin6_addr.s6_addr[1] = 0x80; addr.sin6_addr.s6_addr[2] = 0x00; addr.sin6_addr.s6_addr[3] = 0x00; addr.sin6_addr.s6_addr[4] = 0x00; addr.sin6_addr.s6_addr[5] = 0x00; addr.sin6_addr.s6_addr[6] = 0x00; addr.sin6_addr.s6_addr[7] = 0x00; addr.sin6_addr.s6_addr[8] = 0x02; addr.sin6_addr.s6_addr[9] = 0x40; addr.sin6_addr.s6_addr[10] = 0x8c; addr.sin6_addr.s6_addr[11] = 0xff; addr.sin6_addr.s6_addr[12] = 0xfe; addr.sin6_addr.s6_addr[13] = 0x94; addr.sin6_addr.s6_addr[14] = 0x45; addr.sin6_addr.s6_addr[15] = 0x1e; ret = connect(s, (struct sockaddr*)&addr, sizeof(addr)); if (ret == -1) { err = errno; printf("connect failure, errno = %d\n", err); } } 

结果总是“connect failure,errno = 22”问题在哪里?

Solutions Collecting From Web of "IPv6:连接()总是与errno 22失败"

如果要使用链路本地地址,则必须将sin6_scope_id设置为与链路上的网络设备的设备索引相匹配(这就是为什么您必须为ping6命令指定-I eth1ping6 )。

你可以让getaddrinfo()为你做所有的努力,包括设置范围ID(注意地址末尾的%eth1 )和端口:

 struct addrinfo hints = { 0 }; struct addrinfo *res; int gai_err; int s; hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; gai_err = getaddrinfo("fe80::240:8cff:fe94:451e%eth1", "554", &hints, &res); if (gai_err) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(gai_err)); return 1; } s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (s < 0) { perror("socket"); return 1; } if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { perror("connect"); return 1; }