Linux系统笔记(十)网络系统

343 阅读2分钟

一、Socket通信

进程间通信,其实是通过内核的数据结构完成的, 主要用于在一台 Linux 上两个进程之间的通信。但是,一旦超出一台机器的范畴,我们就需要一种跨机器的通信机制。

socket 接口大多数情况下操作的是传输层,更底层的协议不用它来操心。在传输层有两个主流的协议 TCP 和 UDP,所以我们的 socket 程序设计也是主要操作这两个协议。

从本质上来讲,所谓的建立连接,其实是为了在客户端和服务端维护连接,而建立一定的数据结构来维护双方交互的状态,并用这样的数据结构来保证面向连接的特性。TCP 无法左右中间的任何通路,也没有什么虚拟的连接,中间的通路根本意识不到两端使用了 TCP 还是 UDP。

所谓的连接,就是两端数据结构状态的协同,两边的状态能够对得上。符合 TCP 协议的规则,就认为连接存在;两面状态对不上,连接就算断了。

流量控制和拥塞控制其实就是根据收到的对端的网络包,调整两端数据结构的状态。TCP 协议的设计理论上认为,这样调整了数据结构的状态,就能进行流量控制和拥塞控制了,其实在通路上是不是真的做到了,谁也管不着。

所谓的可靠,也是两端的数据结构做的事情。不丢失其实是数据结构在“点名”,顺序到达其实是数据结构在“排序”,面向数据流其实是数据结构将零散的包,按照顺序捏成一个流发给应用层。总而言之,“连接”两个字让人误以为功夫在通路,其实功夫在两端。

TCP 协议的 socket 调用的过程:

  1. 服务端和客户端都调用 socket,得到文件描述符;
  2. 服务端调用 listen,进行监听;
  3. 服务端调用 accept,等待客户端连接;
  4. 客户端调用 connect,连接服务端;
  5. 服务端 accept 返回用于传输的 socket 的文件描述符;
  6. 客户端调用 write 写入数据;
  7. 服务端调用 read 读取数据。