网络字节序
内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分, 网络数据流同样有大端小端之分。
那么如何定义网络数据流的地址呢?
- 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出;
- 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存;
- 因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址;
- TCP/IP协议规定:网络数据流应采用大端字节序,即低地址高字节;
- 不管这台主机是大端机还是小端机, 都会按照这个TCP/IP规定的网络字节序来发送/接收数据;
- 如果当前发送主机是小端, 就需要先将数据转成大端,否则就忽略, 直接发送即可。
概念补充:
字节序:CPU对内存当中的数据进行存取的顺序
大端字节序:低地址存高位
小端字节序:低地址存低位
eg:
------------------->
主机字节序:当前计算机的字节序,一般情况下X86_64机器都是小端机器。
如何判断当前机器是大端还是小端?
#include <stdio.h>
int main()
{
union AB
{
int a;
char b;
}c;
c.a = 1;
if(1 == c.b)
{
printf("当前计算机为小端机器!\n");
}
return 0;
}
为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint32_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint32_t ntohs(uint16_t netshort);
- 这些函数名很好记,h表示host,n表示network,l表示32位长整数,s表示16位短整数。
- 例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。
- 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回;
- 如果主机是大端字节序,这些 函数不做转换,将参数原封不动地返回。
UDP数据传输流程
一张图来说明:
理解服务器缓存
还是画图来说明:
客户端所有的请求通过网络传给服务器之后,都会存入网卡,然后由服务器不同的服务端口获取各自要处理的请求,并放在自己的缓冲区,这个缓冲区由socket来维护。
一条数据的五元组
用送快递的过程来形象解释这几个元素:
- src_ip: 源IP,这个东西是从哪里寄来的;
- dest_ip: 目的IP,这个东西要送往哪里去:
- src_port: 源端口,这个东西是谁寄的;
- dest_port: 目的端口,这个东西要寄给谁;
- protocol: 协议,使用的是哪个快递公司,顺丰/申通/德邦......
Angus_lxy 发布了83 篇原创文章 · 获赞 26 · 访问量 8629 私信 关注