- 论坛徽章:
- 1
|
看看 !IPv4 套接口地址结构
IPv4和IPv6都属于网际协议(所有的网际协议由多个RFC定义),其版本有0、1、2、3和5,但是比较通用的是版本4和6。
版本4是80年代以后使用的比较广泛的主力协议,版本4使用32位的地址结构,主要给TCP、UDP、ICMP和IGMP提供传输分组的服务。
版本6是90年代中期设计出来的,主要变化是使用了128位的大地址结构,版本6主要给TCP、UDP和ICMPv6提供传输分组的服务。
在目前的应用中,有同时支持IPv4和IPv6的,一般称其为“IPv4/IPv6主机”或者"双栈主机"。
对于这两种协议之间的差别,可以到相关的系统中去察看,一般的在/usr/include/netinet/in.h中,各个系统定义的不尽相同,比如对于结构sockaddr_in中成员sin_len,sin_family和sin_port的数据类型的定义在很多unix系统中的定义有一定的差别,不过对于使用者来说,你只要关心它的大小就可以了,至于到底定义为哪一种类型,同样的可以到系统头文件中可以找得到。在Posix.1g中定义的套接口地址结构如下:
IPv4的定义:
struct in_addr {
in_addr_t s_addr;
};
struct sockaddr_in{
unit8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
其中成员sin_zero暂时没有使用到,用来扩充功能,一般在使用时将其初始化为0,事实上,Posix.1g只需要这个结构中的三个成员sin_family、sin_port和sin_addr,加入其他的两项完全是为了兼容性考虑的。在此强调,这个结构中重要的是结构的大小至少要求16字节,每个具体的成员的大小,请到你的系统中去察看,这里不再赘述。
需要说明的是:在实际的网络通讯中,该结构并不参与通信,尽管成员sin_port和sin_addr用在不同主机间的通信中。
IPv6的定义:
struct in6_addr {
unit8_t s6_addr[16];
};
#define SIN6_LEN
struct sockaddr_in6{
unit8_t sin6_len;
sa_family_t sin6_family;
in_port_t sin6_port;
unit32_t sin6_flowinfo;
struct in6_addr sin6_addr;
};
该结构比较特殊的是成员sin6_flowinfo,事实上该成员的32位用来表示不同的含义,如流量控制(低24位)、优先级(下4位)等。
以上所定义的结构,在我们实际的网络编程中,往往要作为某一个套接口函数的参数来使用,由于历史的原因和为了消除特定协议之间的差别,引入了所谓的通用套接口地址结构,定义如下:
struct sockaddr {
unit8_t sa_len;
sa_family_t sa_family;
char sa_data[14];
};
该结构一般的定义在/usr/include/sys/socket.h中,并且在很多系统中套接口函数原型的定义也使用该通用结构,如 int bind(int s, const struct sockaddr *addr, socklen_t addrlen);,这样在我们编写程序的时候,需要将只想特定协议的地址结构的指针类型转化为该通用套接口地址结构,例如:
struct sockaddr_in testserv;
/* other code */
if( ( ret = connect( sockfd, (struct sockaddr * )&testserv,sizeof( testserv ) ) ) < 0 ) {
close(sockfd);
if( errno == EINTR ) {
errno = ETIMEDOUT;
continue;
}
}
/* other code */
以上简单的描述了IPb4和IPv6地址结构之间的差别,以及通用地址结构的使用,不知是否满意楼上所问。 |
|