linux 之文网络编程基础 (二)、大小端、地址地址转换函数
1、tcp、udp特点
(1)TCP 电话系统服务模式的抽象。(面向连接、可靠)
面向连接 需要3次握手。
(2)UDP邮件系统服务的抽象。(面向无连接的)
经过的路由器多,丢包率高。
认为让它可靠。(添加应用层协议。)
2、大小端
2.1 不同的电脑大小端不同,就会造成问题。
- 主机字节序(大小端都有)
- 网络字节序(都是大端)
大端小端是对于高于一个字节的数据类型来说的,比如说int,short等。char 类型的话就不存在大小端的问题。
假如主机想要向网络上传输一个字符数组int x = 0x1234,主机向网络上传输的时候,主机如果是小端序(低尾端),那么 存储的位置分别是:起始地址(低地址)-> 末尾地址(高地址) 分别存 4,3,2,1。 计算机取数据的时候会按找先取高地址,再取低地址的顺序组成这个数 0x1234 ,这样使用的时候才是正确的。
而在网络上传输的数据应该是大端序的(高尾端),即应该是:起始地址(低地址)-> 末尾地址(高地址) ,分别存1,2,3,4 。计算机取数据的时候会按找先取低地址,再取高地址的顺序组成这个数 0x1234 。 这样使用的时候才是正确的。
那如果把一个int x = 0x1234 ,的整型数从本地主机上发送到 网络上,那么必须按照网络上存储的方式进行发送,因此先要转换一下字节序,然后再发送。如果没有转换字节序的话,网络上使用的时候会按照大端序使用,而你将以小端序列的形式存储的话,它从内存里拿到给我们使用的数据就不是0x1234了。
使用的时候,如果涉及到了位运算,不需要考虑大小端的问题,存储和使用没有必然关系。 比如操作 short 型的数据x,注意一下高位低位的顺序就行了。高3位存什么,低13位存什么,搞清楚以后,假如要获取高3位,那么 x & 0x7fff 得到的结果就是高三位。
注意:
- 服务器一般是大端的(因为网络字节序是大端的,服务器为大端的话就不用修改了) 个人的电脑一般是小端的。
- 主机向网络上传输的数据,只要大于两个字节,都需要将主机字节序转换成网络字节序。
3. 大小端转换API
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong); // 返回以网络字节序表示的32位整数
uint16_t htons(uint16_t hostshort);// 返回以网络字节序表示的16位整数
uint32_t ntohl(uint32_t netlong);// 返回以主机字节序表示的32位整数
uint16_t ntohs(uint16_t netshort);//返回以主机字节序表示的16位整数
- h:host
- n:net
- l:long
- s:short
4. 地址转换函数
(1)将字符串类型的地址(称之为点分十进制)转成整型数据
#include <arpa/inet.h>
const char *inet_ntop(int af, const void *src,
char *dst, socklen_t size);
(2) 将32位整型转成点分十进制数
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);