UNIX网络编程---Ipv4与Ipv6的互操作性 从
从现在开始进入第三部分 高级套接字编程
本章讨论IPV4应用进程和IPV6应用进程如何才能彼此通信。
|
IPV4服务器 |
IPV6服务器 |
IPV4客户 |
几乎全部现有客户和服务器程序 |
在12.2节 |
IPV6客户 |
间12.3节 |
对于大多数现有客户和服务器程序的简单修改 |
我们假设这两个客户都发送SYN分节以建立与服务器的连接。IPV4客户主机在一个IPV4数据报中载送SYN,IPV6客户主机在一个IPV6数据报中载送SYN.来自IPV4客户的TCP分节在以太网线上表现为一个以太网首部后跟一个IPV4首部、一个TCP首部以及TCP数据。以太网首部中包含的类型字段值为0x800,它把本以太网帧标识为一个IPV4帧。TCP首部中的端口为9999.而来自IPV6的TCP分节明显不同。
接收数据链路通过查看以太网类型字段把每个帧传递给相应的IP模块。IPV4模块结合其上的TCP模块检测到IIPV4数据报的目的端口对应一个IPV6套接字,于是把该数据报IPV4首部中的源IPV4地址转换为一个等价的IPV4映射的IPV6地址。当accept系统调用把这个已经接受的IPV4客户连接返回给服务器进程时,这个映射后的地址将作为客户的IPV6地址返回到服务器的IPV6套接字。该连接上其余的数据报同样都是IPV4数据报。
把允许一个IPV4的TCP客户和一个IPV6的TCP服务器进程通信的步骤如下:
1)IPV6服务器启动后创建一个IPV6的监听套接字,我们假定服务器把同统配地址捆绑到该套接字。
2)IPV4客户调用gethostname找到服务器主机的一个A记录。服务器主句既有一个A记录,又有一个AAAA记录,因为他同时支持IPV4和IPV6,不过IPV4客户需要的知识一个A记录
3)客户调用connect,导致客户主机发送一个IPV4SYN到服务器主机
4)服务器主机接受这个目的为IPV6监听套接字的IPV4SYN,设置一个标志指示本连接应使用IPV4映射的IPV6地址,然后响应以一个IPV4 SYN/ACK。该连接建立后,由accept返回给服务器的地址就是这个IPv4映射的IPV6地址。
5)当服务器主机往这个IPV4映射的IPV6地址发送TCP分节时,其IP栈产生目的地址为所映射IPV4地址的IPV4载送数据报。因此,客户和服务器之间的所有通信都使用IPV4的载送数据报。
6)除非服务器显示检测这个IPV6地址是不是一个IPV4映射的IPV6地址,否则它永远不知道自己是在与一个IPV4客户同行。
如果收到一个目的地为某个IPV6套接字的IPV4数据报,那么内核把与该数据报的源IPV4地址对应的IPV4映射地IPV6地址作为由ACCEPT或recvfrom返回的对端IPV6地址。这样映射是可行的,因为任何一个IPV4地址总能表示成一个IPV6地址。客户和服务器之间交换的是IPV4数据报。
大多数双栈主机在处理监听套接字时应使用一下规则:
1)IPV4监听套接字只能接受来自IPV4客户的外来链接
2)如果服务器有一个绑定了统配地址的IPV6监听套接字,而且该套接字未设置IPV6_V6ONLY套接字选项,那么该套接字揖能接受来自IPV4客户的外来链接,又能接受来自IPV6客户的外来链接。对于来自IPV4客户的链接而言,其服务器端的本地地址将是与某个本地IPV4地址对应的IPV4映射的IPV6地址。
3)如果服务器有一个IPV6监听套接字,而且绑定在其上的是出IPV4映射的IPV6地址之外的某个非统配IPV6地址,或者绑定在其上的是统配地址,不过还设置了IPV6_V6ONLY套接字选项,那么该套接字这能接受来自IPV6客户的外来链接。
在上一节中介绍的IPV4服务器只能接受IPV4的链接,这里可行的原因是客户运行在一个双栈主机上。
有写应用程序需要知道读端的IP地址是不是一个IPV4映射的IPV6地址。头文件<netinet/in.h>中定义了12个宏用于测试
把这些IPV4应用程序转换成用在IPV6并不费劲,如果在源代码级上把一个应用程序转换成用上IPV6并发布,那么需要考虑接纳者的系统是够支持IPV6
PS:
双栈主机上的IPV6服务器既能服务于IPV4客户,又能服务于IPV6客户。IPV4客户发送给这种服务器仍然是IPV4数据报,不过服务器的协议栈会把客户主机的地址转换成一个IPV4映射的IPV6地址,因为IPV6服务器仅仅处理IPV6套接字地址结构。
双栈主机上的IPV6客户能欧冠和UIPV4服务器通信。客户的解析器会把服务器主机所有的A记录作为IPV4映射的IPV6地址返回给客户,而客户指定这些地址之一调用connect将会使双栈发送一个IPV4SYN分节。