套接字中的一些数据格式的转换与统一

由于网络协议族的不同、大小端的不同、人与机器对数据的识别不同,所以要对一些数据结构进行统一和转换。

1.对于网络协议族:有IPV4,IPV6,UNIX,DATALINK等的不用,导致他们对应的套接字地址结构也不同。

    ipv4的套接字地址结构 

struct sockaddr_in {

            unit8_t               sin_len;

            sa_family_t      sin_family;

            int_prot_t          sin_port;

           struct in_addr   sin_addr;

            char                   sin_zero[8];

};

其中 

struct in_addr {

           in_addr_t           s_addr;

};


ipv6的套接字地址结构

struct  sockaddr_in6 {

           uint8_t                sin6_len;

           sa_family_t       sin6_family;

           in_port_t            sin6_port;

           uint32_t             sin6_flowinfo;

           struct  in6_addr   sin6_addr;

};

其中   

struct   in6_addr {

          unit8_t                s6_addr[16];

};

从这两个结构中我们可以找出一些结构变量的共同点:①有标明是何种协议族的成员变量sa_family,②有标明地址的成员变量 ③有标明端口的变量 ④有标明地址结构长度的变量。


对于这种情况,为了能够用共同的函数对不同的套接字地址结构作统一的处理,就引进了一个结构体:通用套接字地址结构

struct  sockaddr {

        unit8_t           sa_len;

        sa_family_t    sa_family;

        char                  sa_data[14];

};

其实对函数传入不同套接字地址结构指针完全可以用void *可以实现,但是由于历史原因,该结构早于void *的出现,所以沿用下来。

2.对大小端的统一。这种情况出现是由于:网络字节序均为大端字节序,而不同的主机系统的字节序可能会不同,可能是大端也可能是小端。于是为了实现对主机与网络之间数据的正确传送,就需要大小端转换了。

用如下四个函数

#include <netinet/in.h>

uint16_t   htons(uint16_t  host16bitvalue);

uint32_t   htonl(unit32_t   host32bitvalue);


unit16   ntohs(uint16_t   net16bitvalue);

unit32   ntohl(unit32_t    net32bitvalue);

为了便于记忆 h 为host  n为network,s 为short,l 为long ,注意不可将s简单的理解为short型,long理解为long型,因为64位的系统long型为64位,但是这些函数只能处理16位或者32位的数,64位的是无法处理的。

3.对网络地址,机器与人的识别的统一转换

计算机识别网络地址是用二进制的,而为了便于理解,人为的网络地址是字符串的。所以要实现这两者的转换,于是又下面几个函数。

inet_aton,inet_addr,inet_ntoa,inet_pton,inet_ntop

注意:前三个只能处理IPV4,后两个既可以处理IPV4也可以处理IPV6,而且后两个更为常用

为了便于记忆:可将a理解为ASCII,n理解为numberic,p理解为presentation(表达式)


int  inet_aton(const char *strptr,struct in_addr  *addrptr);

in_addr_t  inet_addr(const char *strptr);

char *inet_ntoa(struct  in_addr  inaddr);


int inet_pton(int family,const char *strptr,void *addrptr);

const char *inet_ntop(int family,const void *addrptr,char *strptr,size_t len);


为了便于记忆总结下着两组函数的共同点:

①如果函数的参数中 源和目标同时存在即既有str 又有addr的话,被转换的总在转换成的前面。

②如果最终是转换成str的话,其返回的一个是个指向char的指针。

还有注意点:

①后一组将为通用的函数有了family这个参数的原因是 其皆可以处理IPV4又可以处理IPV6

②最后一个之所以加了个len的参数,是给定返回字符串的长度,防止返回溢出调用者的缓冲区。

参考文献:《unix网络编程第一卷》

《unix环境高级编程》第二版

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值