Linux -- 端口号、套接字、网络字节序、sockaddr 结构体
目录
什么是端口号?
什么是套接字?
网络字节序
struct sockaddr 结构体
什么是端口号?
我们日常上网的时候,主机其实是在进行两种操作:
1、把远端的数据拉取到本地,比如刷抖音的时候,手机向远端的服务器请求访问,存储在远端服务器的数据发送到手机,我们才可以在手机上看到视频;
2、把本地的数据发送到远端,比如用户上传视频到网上,其实就是把数据发送到远端的服务器。
我们打开淘宝、京东、抖音的时候,其实就是在主机中启动了对应的进程,客户端 和 服务端互相发送数据,本质就是两个进程在进行网络通信!
我们在刷手机时,会打开很多个 APP,我们一会刷抖音,一会刷B站,一会刷淘宝,手机会收到这些应用 对应的服务器 发来的报文,传输层解析报文之后,需要进一步确定把报文发给应用层的哪一个进程,抖音服务器发来的报文就要交给手机中抖音的进程来处理,淘宝也是同理,所以就需要唯一的标识符来区分每一个网络进程,这个唯一的标识符就是 端口号 port !一个端口号只能被一个进程占用!
什么是套接字?
用 端口号 还不能够在 互联网 中唯一的确定一个进程,因为 互联网 中存在多台主机!我们需要同时确定要把数据发给哪个主机、由该主机的哪个端口号来接收数据!!也就是 IP 地址 和 端口号 可以在互联网中定位唯一的进程!!套接字就是 IP 地址 + 端口号!有了套接字,互联网中的两个进程就可以找到彼此。
就像在网购中填写收货信息,不仅需要填写电话,还需要填写地址,才可以确定这个快递到底要发到哪个地方、发给谁。
网络字节序
内存中的多字节数据相对于内存地址有大端小端之分,内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分, 网络数据流同样有大端小端之分。
TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节。不管这台主机是大端机还是小端机,都会按照这个TCP/IP规定的网络字节序来发送/接收数据;如果当前发送主机是小端,,就需要先将数据转成大端;否则就忽略,直接发送即可。
可以调用库函数做网络字节序和主机字节序的转换:
其中 h 就是 host,n 就是 net,s 就是 short,l 就是 long ,方便记忆。
从主机字节序转换到网络字节序
将一个16位无符号整数从主机字节序转换为网络字节序:
#include<arpa/inet.h> uint16_t htons(uint16_t hostshort);
将一个32位无符号整数从主机字节序转换为网络字节序:
#include<arpa/inet.h> uint32_t htonl(uint32_t hostlong);
从网络字节序转换到主机字节序
将一个16位无符号整数从网络字节序转换为主机字节序:
#include<arpa/inet.h> uint16_t ntohs(uint16_t netshort);
将一个32位无符号整数从网络字节序转换为主机字节序:
#include<arpa/inet.h> uint32_t ntohl(uint32_t netlong);
struct sockaddr 结构体
各种网络协议的地址格式并不相同。sockaddr_in
结构体用于 IPv4 互联网协议套接字地址。sockaddr_un
结构体用于 Unix域(本地)套接字。
struct sockaddr
是一个通用的套接字地址结构体,它被用来存储不同类型的网络协议地址,这样可以方便 socket 相关函数传参。