bio nio aio

TCP/IP 通信基础知识
  • 对于 TCP 通信来说,每个 TCP Socket 在内核中都有一个发送缓冲区和一个接收缓冲区
  • TCP 的全双工的工作模式及 TCP 的滑动窗口便依赖于这两个独立的 Buffer 及此 Buffer 的填充状态
  • 接收缓冲区把数据缓存入内核,若应用进程一直没有调用 Socket 的 read 方法进行读取的话,则此数据会一直被缓存在接收缓冲区内。不管进程是否读取 Socket,对端发来的数据都会经由内核接收并且缓存到 Socket 的内核接收缓冲区中
  • read 所做的工作,就是把内核接收缓冲区中的数据复制到应用层用户的 Buffer 里面
  • 进程调用 Socket 的 send 发送数据的时候,最简单的情况(也是一般情况)是将数据从应用层用户的 Buffer 里复制到 Socket 的内核发送缓冲区中,然后 send 便会在上层返回
TCP/IP 的滑动窗口和流量控制机制
  • Socket 的接收缓冲区被 TCP 和 UDP 用来缓存网络上收到的数据,一直保存到应用进程读走为止
  • 对于 TCP 来说,如果应用进程一直没有读取,则 Buffer 满了之后,发生的动作是:通知对端 TCP 协议中的窗口关闭,保证 TCP 套接口接收缓冲区不会溢出,保证了 TCP 是可靠传输的,这个便是滑动窗口的实现
  • 因为对方不允许发出超过通告窗口大小的数据,所以如果对方无视窗口大小而发出了超过窗口大小的数据,则接收方 TCP 将丢弃它,这就是 TCP 的流量控制原理。而对于 UDP 来说,当接收方的 Socket 接收缓冲区满时,新来的数据报无法进入接收缓冲区,此数据报就会被丢弃,UDP 是没有流量控制的,快的发送者可以很容易地淹没慢的接收者,导致接收方的 UDP丢弃数据报
阻塞模式
  • 对于读取 Socket数据的过程而言,如果接收缓冲区为空,则调用 Socket 的 read 方法的线程会阻塞,直到有数据进入接收缓冲区中
  • 而对于写数据到 Socket 中的线程而言,如果待发送的数据长度大于发送缓冲区的空余长度,则会阻塞在 write 方法上,等待发送缓冲区的报文被发送到网络上,然后继续发送下一段数据,循环上述过程直到数据都被写入到发送缓冲区为止

从上述的程来看,传统的 Socket 阻塞模式直接导致每个 Socket 都必须绑定一个线程来操作数据,参与通信的任意一方如果处理数据的速度较慢,则都会直接拖累另一方,导致另一方的线程不得不浪费大量的时间在 I/O 等待上,所以,每个 Socket 要绑定一个单独的线程正是传统Socket 阻塞模式的根本“缺陷”。之所以这里加了“缺陷”两个字,是因为这种模式在一些特定场合下效果是最好的,比如只有少量的 TCP 连接通信,双方都非常快速地传输数据,此时这种模式的性能最高

非阻塞 模式就是要解决 I/O 线程与 Socket 解耦的问题,因此,它引入了事件机制来达到解耦的目的。我们可以认为 N

打赏
支付宝 微信
上一篇 下一篇