套接字地址结构及大小端笔记

来源:互联网 发布:任子行网络评价 编辑:程序博客网 时间:2024/06/06 04:46

《unix网络编程》第三章笔记

每个协议族都定义了自己的套接字地址结构。这些结构体的名字均以sockaddr_开头,并以对应每个协议族的唯一后缀结尾。

IPV4套接字地址结构,以sockaddr_in命名,定义在<netinet/in.h>头文件中

struct in_addr {in_addr_t s_addr;// uint32_t IPV4 address, network byte ordered}struct sockaddr_in {uint8_t sin_len; // length of structure(16)sa_family_t sin_family; // AF_INETin_port_t sin_port; // uint16_t TCP or udp port number, network byte orderedstruct in_addrsin_addr; // 32bit IPV4 address, network byte orderedchar sin_zero[8];// unused}


每当一个套接字函数需要一个指向某个套接字地址结构的时候,都需要将这个指针强制类型转换成一个通用套接字结构的指针。通用套接字结构如下:

struct sockaddr {uint8_tsa_len;sa_family_t sin_family; // AF_INETchar sa_data[14];// protocol address}


注意到上面结构体中的端口号和地址需要以网络字节序存储。所谓网络字节序就是大端存储。

书中定义大小端是这么描述的:术语小端和大端表示多个字节值的哪一段(小端或大端)存储在该值的起始地址。

把某个系统所用的字节序称为主机子节序,可能是大端,也可能是小端。判断主机字节序程序:

<span style="font-size:18px;">int main(void){    union {    short s;    char c[sizeof(short)];    }un;    un.s = 0x0102;    if (sizeof(short) == 2)    {           if (un.c[0] == 1 && un.c[1] == 2)        {               printf("big-endian\n");        }           else if (un.c[0] == 2 && un.c[1] == 1)        {               printf("little-endian\n");        }           else        {               printf("unknow\n");        }       }            else    {           printf("sizeof(short) == %d\n", sizeof(short));    }       return 0;}</span>


两个系统间进行网络通讯是以大端方式发送,如主机序是小端的,需要转换成大端存储再进行发送。两种字节序之间的转化函数:

#include <netinet/in.h>uint16_t htons(uint16_t host16bitvalue);uint32_t htonl(uint32_t host32bitvalue);uint16_t ntohs(uint16_t net16bitvalue);uint32_t ntohl(uint32_t net32bitvalue);

h代表host,n代表network,s代表short,l代表long。即使在64位主机上,s和l仍旧表示16位和32位的值。

0 0