客户端和服务端一次网络交互
网络交互步骤
- 客户端进程调用
write
将消息写到操作系统内核为套接字分配的发送缓冲send buffer
。 - 客户端操作系统内核将发送缓冲的内容发送到网卡,网卡硬件将数据通过「网际路由」送到服务器的网卡。
- 服务器操作系统内核将网卡的数据放到内核为套接字分配的接收缓冲
recv buffer
。 - 服务器进程调用
read
从接收缓冲中取出消息进行处理。 - 服务器进程调用
write
将响应消息写到内核为套接字分配的发送缓冲send buffer
。 - 服务器操作系统内核将发送缓冲的内容发送到网卡,网卡硬件将数据通过「网际路由」送到客户端的网卡。
- 客户端操作系统内核将网卡的数据放到内核为套接字分配的接收缓冲
recv buffer
。 - 客户端进程调用
read
从接收缓冲中取出消息返回给上层业务逻辑进行处理。
步骤 5~8 和 1~4 是一样的,只不过方向是反过来的,一个是请求,一个是响应。
网络耗时在哪里呢?
write
write
不是等到对方收到消息才会返回,它只负责将数据写到本地操作系统内核的发送缓冲就返回了。剩下的事交给操作系统内核异步将数据送到目标机器。
如果发送缓冲满了,那么就需要等待缓冲空出空闲空间来。这是写操作 IO 操作真正耗时的地方。
write
耗时的多少实质是本地操作系统内核的发送缓冲的剩余空间是否够 write
的字节数(不够就阻塞等待或者超时返回)。
read
read
不是从目标机器拉取数据才返回的,它只负责将数据从本地操作系统内核的接收缓冲中取出来。
如果缓冲是空的,就会等待直到数据到来。这是读操作 IO 操作真正耗时的地方。
read
耗时的多少实质是本地操作系统内核的接收缓冲区的数据是否够 read
的要读取字节数(不够就阻塞等待够或者超时返回)。
总结
从底层来理解网络,确实可以清晰很多。