- IPV6地址
IPv6地址有128位,通常使⽤16进制表⽰因此128位可以表⽰成8组。
例:2409:891E:9A40:48ED:250:C2FF:FEE7:3677
1.1 Link-Local Address 链路本地地址 使用netif_create_ip6_linklocal_address生成
1.2 Global Address,分为有状态及无状态
1.2.1 无状态(Stateless):根据路由通告报文RA(Router Advertisement)包含的prefix前缀信息自动配置IPv6地址.如移动设备、办公室内PC机,只需要上IPv6互联网,并不需要对外提供服务,可以采用无状态IP
1.2.2 有状态(Stateful):通过DHCPv6方式获得IPv6地址.如对外提供服务,通常需要采用有状态IP。因为业务IP的突然变化容易导致业务中断(除非做好服务发现)
1.2.3 总结:客户端可以采用无状态,服务器端一般采用有状态
- 单播 组播 任意播
http://www.360doc.com/content/21/1227/20/74768826_1010626421.shtml
- 代码修改
- 打开宏:LWIP_IPV6
- 初始化
3.2.1 netif打开组播功能
netif->flags = netif->flags |NETIF_FLAG_MLD6;
3.2.2 netif初始化IPV6发送接口
netif->output_ip6 = ethip6_output;
3.2.3生成链路本地地址
netif_create_ip6_linklocal_address(netif, 1);
3.2.4设置自动配置ipv6地址
netif_set_ip6_autoconfig_enabled(netif, 1);
附:IPV6客户端代码
int ipv6_connect(const char *host, const char *service)
{
int sockfd, ret;
struct addrinfo hints, *res, *ressave;
char buff[128] = {0};
char recv_buf[128]={0};
memset(&hints, 0, sizeof(hints));
if(host[0] == 'b') // "baidu for ipv4 test"
{
hints.ai_family = AF_INET;
LOG(LOG_LVL_INFO, "ipv6_connect start ipv4\r\n");
}
else
{
hints.ai_family = AF_INET6;
LOG(LOG_LVL_INFO, "ipv6_connect start ipv6\r\n");
}
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_IP;
LOG(LOG_LVL_INFO, "ipv6_connect start\r\n");
if (0 != (ret = lwip_getaddrinfo(host, service, &hints, &res)))
{
LOG(LOG_LVL_INFO, "lwip_getaddrinfo error\r\n");
return -1;
}
do{
if (-1 == (sockfd = lwip_socket(res->ai_family, res->ai_socktype, res->ai_protocol)))
{
LOG(LOG_LVL_INFO, "create lwip_socket error\r\n");
res = res->ai_next;
break;
}
if(hints.ai_family == AF_INET6)
{
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)res->ai_addr;
ip6_addr_t fromaddr;
inet6_addr_to_ip6addr(&fromaddr, &addr->sin6_addr);
LOG(LOG_LVL_INFO, "connect ip: %s\r\n",inet6_ntoa(fromaddr));
}
else
{
struct sockaddr_in *addr = (struct sockaddr_in *)res->ai_addr;
ip4_addr_t fromaddr;
inet_addr_to_ip4addr(&fromaddr, &addr->sin_addr);
LOG(LOG_LVL_INFO, "connect ip: %s\r\n",inet_ntoa(fromaddr));
}
if (lwip_connect(sockfd, res->ai_addr, res->ai_addrlen) != 0)
{
LOG(LOG_LVL_INFO, "lwip_connect error errno = %d\r\n",errno);
break;
}
else
{
LOG(LOG_LVL_INFO, "lwip_connect succeed\r\n");
sprintf(buff,"GET /times HTTP/1.1\r\nHost:%s\r\n\r\n", host);
lwip_send(sockfd, buff, strlen(buff), 0);
memset(recv_buf, 0, sizeof(recv_buf));
ret = lwip_read(sockfd, recv_buf, 128);
if(ret > 0)
{
LOG(LOG_LVL_INFO, "lwip_read %s\r\n",recv_buf);
}
else
{
LOG(LOG_LVL_INFO, "lwip_read failed\r\n");
}
}
}while(0);
close(sockfd);
freeaddrinfo(res);
return 0;
}
综上,IPV6客户端编程与IPV4的客户端编程只有一处区别,即:ai_family属性值不同,另外注意域名解析gethostbyname不支持ipv6,只能用getaddrinfo.