网络编程第三章总结(地址族与数据序列)

本文总结了网络编程中的地址族与数据序列,包括IPv4与IPv6的区别,端口号的分配规则,网络地址结构体的表示,网络字节序与地址转换的方法,以及如何初始化和分配网络地址。
摘要由CSDN通过智能技术生成

第三章、地址族与数据序列

3.1、分配给套接字的IP地址与端口号

IP地址分为IPv4 和IPv6,书中主要讲解IPv4,但其实截至到目前IPv4已经全部耗尽,开始使用IPv6了。
网络地址分类:
在这里插入图片描述

IPv4一共分为ABCDE5类,但E类一般不使用。可以通过IP第一个字节判断网络地址占用的字节数。

A类地址  (0   - 127)   0  开始
B类地址  (128 - 191)   10 开始
C类地址  (192 - 223)   110开始

用于区分套接字的端口号:
端口号就是同一操作系统内为区分不同套接字而设置的,因此无法将一个端口号分配给不同的套接字。端口号由16位构成,可分配的端口号范围是0-65535,但0-1023是知名端口号,一般给特定程序。由于TCP和UDP不共用端口号,所以两个协议可以同时使用一个端口号。(比如都使用9000这个端口号)
目标地址 = IP地址 + 端口号

3.2、地址信息的表示

IPv4结构体主要参数:

struct sockaddr_in
{
	sa_family_t     sin_family;  //地址族
	uint16_t        sin_port;    //16位端口号
	struct in_addr  sin_addr;    //32位IP
	char            sin_zero[8]; //不使用
};

结构体 sockaddr_in的成员分析:
成员sin_family:每种协议族适用的地址族均不同。

AF_INET   IPv4网络协议使用的地址族
AF_INET6  IPv6网络协议使用的地址族
AF_LOCAL  本地通信中采用的UNIX协议的地址族

成员sin_port:保存16位端口号,以网络字节序保存。
成员sin_addr:保存32位IP地址信息,也以网络字节序保存。
成员sin_zero:无特殊含义,必要时需要填充0.比如Bind处(bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)))

struct sockaddr{
	sa_family_t sin_family;  //地址族
	char        sa_data[14]; //地址信息
}
此结构体成员sa_data保存的地址信息中需要包含IP地址和端口号,剩余部分应填充0.

3.3、网络字节序和地址转换

字节序与网络字节序
CPU向内存保存数据的方式有2种,这意味着CPU解析数据的方式也分为两种;1、高位字节放低位地址(大端序);2、高位字节放高位地址(小端序)。在网络传输数据时约定统一网络字节序为大端序。

字节序转换:

unsigned/signed short/long htons/ntohs(unsigned short/long);

htons中h代表主机字节序,n代表网络字节序 s表示short l表示long htons 表示 h to n s 把short的主机字节序转化为网络字节序。
s作为后缀的函数中,s代表两个字节short,用于端口转换;以l作为后缀的函数中,l代表4个字节,用于IP地址转换。

3.4、网络地址的初始化和分配

sockaddr_in中保存地址信息为32位整数型,为了分配地址,需要将字符串转化为32位整数型数据。

int_addr_t inet_addr(const char * string);//成功返回32位大端序整数型值,失败返回INADDR_NONE。

inet_aton函数与inet_addr函数在功能上完全相同,也将字符串形式IP地址转化为32位网络字节序整数并返回。

int inet_aton(const char *string, struct in_addr *addr);//成功返回1,失败返回0.
//string:需要转换为IP的字符串,addr将保存转换结果的in_addr结构体变量的地址值
char * inet_ntoa(struct in_addr adr);//成功返回转换的字符串地址值,失败返回-1.

网络初始化
eg:

struct sockaddr_in addr;
char * serv_ip = "211.217.168.13";
char * serv_port = "9190";
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(serv_ip);
addr.sin_port = htons(atoi(serv_port)); //基于字符串的端口号初始化。

使用 INADDR_ANY,只需要修改一行代码就行了,利用常数INADDR_ANY分配服务器IP地址。

addr.sin_addr.s_addr = htonl(INADDR_ANY);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值