基于LWIP2.1.3 IPV6开发笔记

  1. 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 总结:客户端可以采用无状态,服务器端一般采用有状态

  1. 单播 组播 任意播

http://www.360doc.com/content/21/1227/20/74768826_1010626421.shtml

  1. 代码修改
    1. 打开宏:LWIP_IPV6
    2. 初始化

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.

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值