Unix网络编程学习笔记之第12章 IPv4与IPv6的互操作性

原创 2015年07月09日 17:23:47

一、 简介

假设我们本章讨论的主机都是支持双栈的,即支持IPv4地址,也支持Ipv6地址。

我们本次讨论的点:客户端与服务器端使用的是不同类型的地址。因为相同类型的地址没什么可讲的。

 

二、 IPv4客户端与IPv6服务器

即,客户端使用IPv4地址套接字来通信,服务器端使用IPv6地址套接字通信。

原理:

0. 首先IPv6服务器主机保证既有IPv4地址,又有IPv6地址。

1. IPv4客户端通过getaddrinfo函数,找到服务器端的IPv4地址,然后进行连接。

2. 来自客户端的IPv4的SYN到达服务器端,服务器端内核就把这个IPv4的SYN,映射为IPv6的SYN(就是把IPv4的IP地址映射为IPv6的IP地址),然后交给进程。所以服务器端accept、recvfrom的套接字地址都是IPv6的。

3. 然后服务器端进程进行响应ACK,进程发送一个IPv6的ACK到内核,内核查看目的地址,就知道这个IPv6的地址是经过映射过来的。所以内核就是这个IPv6地址映射为IPv4地址发送出去。

4. 这样就正常通信了,即实际上还是通过IPv4包进行通信的。然而服务器和客户端进程都不知情的,这些工作由服务器内核完成。

注意:如果IPv6服务器主机没有IPv4地址,则这样的通信无法完成。

 

三、 IPv6客户端与IPv4服务器

即,客户端使用IPv6地址套接字来通信,服务器端使用IPv4地址套接字通信。

原理:

0. 首先IPv4服务器主机中没有IPv6地址。

1. IPv6客户端通过getaddrinfo函数,且hints的结构中的标志为AI_V4MAPPED。则我们就可以通过getaddrinfo函数得到服务器主机的IPv4地址映射的IPv6地址。

2. 然后客户端使用这个IPv6地址调用connect,而内核检测出这个IPv6的地址是映射的,所以就会把这个IPv6地址转成IPv4地址,然后发送出去。

3. 这样IPv4服务器就得到了IPv4的SYN,然后响应IPv4的ACK。

4. 客户端接收到这个IPv4的ACK后,内核就会把这个IPv4的ACK转为IPv6的ACK,从而进行通信。

5. 实际上还是通过IPv4的包进行通信的。服务器和客户端进程不知情。由客户端内核完成。

注意:如果此时IPv4服务器主机有IPv6地址,则尽管hints的结构中的标志为AI_V4MAPPED,但是getaddrinfo也返回原有的IPv6地址,这样的话,双方无法完成通信。这时我们可以通过在主机名上加-4,来规定只查询A记录。这样就可以通信了。

 

四、 错误的组合

上述的两种错误情况,都是因为内核无法将IPv6地址转为为IPv4地址,因为IPv6有128位,而IPv4地址只有32位。

总结一下:即

 

即:

1. 显然如果双方都是单栈主机,也双方的协议必须相同。

2. IPv4双栈客户,无法与IPv6的单栈服务器通信。即上面的第1种错误情况。

3. Ipv6单栈客户,无法与Ipv4的双栈服务器通信。

4. IPv6双栈客户是否可以与IPv4双栈客户通信取决于实现,即如果getaddrinfo获取的是IPv4映射的IPv6地址,则可以通信。如果获取的是真正的IPv6地址,则无法通信。

5. 其实问题就是在于实现了IPv6的主机上,尽量也要实现IPv4,这样的话,我们可以看到,去除表的第二行和第而列,则表中的(无)就没有了。只剩下(无*)。

 

五、 IPv6地址测试宏

有一些IPv6应用程序想要知道,某个IPv6地址到底是IPv4映射过来的,还是本身就是IPv6地址。我们可以使用宏:

#include     <netinet/in.h>
int IN6_IS_ADDR_V4MAPPED(const structin6_addr* apt);

来进行检测。

 

六、 建议

尽量写一些与具体协议无关的函数。

尽量使用与具体协议无关的函数。

还有从上述的表中可以看出,我们在编写服务器时,在服务器主机支持双栈协议的情况下,把服务器的地址写成IPv6地址,这样可以接收任何协议的客户端。

 

 

IPv4 和 IPv6的互操作性

IPv4客户与IPv6服务器通信 步骤如下:     1、IPv6服务器启动后创建一个IPv6监听套接字,我们假定服务器把通配地址绑定到该套接字     2、IPv4客户调用gethostbyname...
  • u012062760
  • u012062760
  • 2015年04月02日 16:55
  • 845

IPv4和IPv6的互操作性

最近几年,IPv4可能是已经接近枯竭了,所以我们又推出了IPv6,在未来几年内,我们的IP可能是IPv6的了,但是对于现存的大量的基于IPv4代码的服务器和客户端,我们是不是都得做出大量的更新?或许我...
  • yiling2012
  • yiling2012
  • 2014年11月22日 17:16
  • 236

IPv4与IPv6的互操作性

IPv4与IPv6的互操作性ipv4客户与ipv6服务器 IPv6客户和IPv4服务器 IPv6地址测试宏IPv4与IPv6的互操作性 双栈主机的一个基本特性是其上的IPv6服务器既能处理IPV4...
  • yudiyanwang
  • yudiyanwang
  • 2016年12月11日 17:16
  • 139

UNXI网络编程笔记 第12章IPV4与IPV6的互操作性

IPv4客户与IPv6服务器: 地址转换是由服务器端处理的 假设服务器支持双协议栈,而且即有一个IPv4地址,由有一个IPv6地址。服务器绑定了IPv6的通配地址。此时IPv4客户端要与服务器...
  • standmyground
  • standmyground
  • 2016年09月24日 12:24
  • 199

网络编程:Socket编程从IPv4转向IPv6支持

目前运行主流的IT系统中,用于解决分布式系统内部模块及不同的系统间通信的一种主要的解决方案就是使用套接字Socket来开发应用。由于当前大部分正在运行的IT系统中使用套接字Socket开发环境基本上都...
  • Blaider
  • Blaider
  • 2014年10月09日 11:22
  • 5167

OSI参考模型——网络层:IPv4协议和IPv6协议详解

博文目录一、网络层的基本概念 二、网络层IP协议的基本内容 三、IPv4分组的格式 四、IPv4分组的地址分类和表示 五、IPv4地址的子网划分 六、CIDR(无类别域间路由) 七、IPv...
  • jeffleo
  • jeffleo
  • 2016年12月30日 15:10
  • 1337

UNIX网络编程--Ipv4与Ipv6的互操作性(十二)

UNIX网络编程---Ipv4与Ipv6的互操作性  从 从现在开始进入第三部分  高级套接字编程 一、概述 本章讨论IPV4应用进程和IPV6应用进程如何才能彼此通信。   IPV4服务...
  • yusiguyuan
  • yusiguyuan
  • 2013年09月20日 22:24
  • 1373

iOS测试:IPV4下搭建IPV6网络 测试app在IPV4和IPV6下的兼容性

随着IPv4地址池耗尽在即,企业和移动运营商正越来越多地部署IPv6 DNS64和NAT64网络。一个DNS64 / NAT64网络是继续提供通过翻译访问IPv4的内容仅IPv6网络。因此确保IPv6...
  • u013043666
  • u013043666
  • 2016年06月15日 13:46
  • 2333

网络层学习之二(IPv4及IPv6地址及相关协议)

IP(internet protocol)协议是TCP/IP协议族的核心协议,是因特网的网络层。当前的版本号是4,也称为IPv4,下一代IP协议的版本号为6即IPv6。正如描述的网络层功能一样,IP层...
  • goodluckwhh
  • goodluckwhh
  • 2013年08月10日 12:12
  • 6477

IP&IP地址、ipv4&ipv6、子网掩码、网段计算、网络广播ID计算、默认网关、DNS服务器、DHCP服务器

IP&IP地址、ipv4&ipv6、子网掩码、网段计算、网络广播ID计算、默认网关、DNS服务器、DHCP服务器等知识...
  • qq_36743482
  • qq_36743482
  • 2017年06月23日 15:55
  • 1180
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Unix网络编程学习笔记之第12章 IPv4与IPv6的互操作性
举报原因:
原因补充:

(最多只允许输入30个字)