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

《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_INET
	in_port_t 	sin_port; // uint16_t TCP or udp port number, network byte ordered
	struct in_addr	sin_addr; // 32bit IPV4 address, network byte ordered
	char 		sin_zero[8];// unused
}


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

struct sockaddr {
	uint8_t		sa_len;
	sa_family_t 	sin_family; // AF_INET
	char 		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位的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值