dduo518 / hexo-blog

hexo静态blog点击 https://github.com/chong0808/hexo-blog/issues
3 stars 0 forks source link

TCP #45

Open dduo518 opened 3 years ago

dduo518 commented 3 years ago

TCP位于运输层

运输层的多路复用与多路分解

TCP提供可靠数据传输,通过流量控制、序号、确认、定时器保证tcp争取地、有序地将数据从发送经常交付给接收进程 TCP还提供了拥塞控制,防止任何一条tcp连接用过多流量淹没通信主机之间的链路和交换设备,力求为每个通过一条拥塞网络链路 的连接平等的共享网络链路带宽 多路分解: 将运输层报文段中的数据交付到正确的套接字的工作,报文段数据(运输层)--->套接字(进程) 多路复用: 在源主机从不同套接字中收集数据块,并为每个数据封装上首部信息,从而生成报文段,然后将报文段传递到网络层,套接字(进程)---> 报文段(运输层)

TCP三次握手四次挥手

三次握手建立连接

TCP连接建立过程中要解决三个问题

  1. 要使每一方能够确知对方的存在
  2. 要允许双方协商一些参数(如最大窗口值、释放使用窗口扩大选项和时间戳选项以及服务质量等)
  3. 能够对运输实体资源(如缓存大小、连接表中的项目)进行分配
    • 第一次报文发送:客户端---> 服务端 客户端进程创建传输控制模块,发出连接请求报文,首部中的同步位SYN=1,顺序位seq=x,此时TCP客户端进入SYN-SENT 状态
    • 第二次报文传输:服务端--->客户端 服务端收到客户端的请求连接报文,同意建立连接,则向客户端发送确认连接报文,报文段中同步位SYN=1,ACK位置位1ACK=1,确认号ack=x+1,顺序号seq=y,此时服务端进入SYN-REVD状态。
    • 第三次报文传输: 客户端--->服务端 客户端收到服务端的确认后,还需要向服务端发送确认号,此时报文段ACK置为1ACK=1,确认好ack=y+1,顺序号为seq=x+1,此时客户端进入ESTABLISHED状态。 服务端收到确认后也进入ESTABLISHED状态
      三次握手的保证

      三次握手保证了一次正常的连接,服务端只有在收到客户端最后的确认连接报文之后才会给连接分配文件句柄及内存空间,这样避免了无效连接大量的占用资源,造成资源负载过高。中间任何一次报文传输异常,服务端都不会为连接分配文件句柄及内存。

      四次挥手释放连接

    • 第一次:客户端--->服务端 客户端应用向服务端发出连接释放报文,并停止再发送数据,主动关闭TCP连接,释放连接报文端首部的终止控制位FIN置为1,此时客户端进入FIN-WAIT-1终止等待1状态,等待服务端的确认
    • 第二次: 服务端---> 客户端 服务端收到连接释放报文后发出确认,此时服务端进入close-wait关闭等待状态,TCP服务器进程这时会通知高层应用进程,此时客户端--->服务端方向的连接释放,也就是TCP处于半关闭half-close状态,即客户端已经没有数据发送,但是服务端如果还有没有发送完的数据,仍然可以继续发送,客户端仍然可以接收,服务端---> 客户端方向的连接未关闭。 此时服务端会做一些最后的数据发送,将未发送完成的数据继续发送 客户端收到第二次的报文确认后进入FIN-WAIT-2终止等待2 状态,等待服务端发送的释放报文段
    • 第三次: 服务端---> 客户端 当服务端已经没有数据向客户端发送的时候,应用进程就会通知TCP释放连接,服务端发出释放报文段,此时服务端进入last-ack最后确认状态,等待客户端的确认。
    • 第四次:客户端--->服务端 客户端收到服务端发出的释放报文段后,发出确认,此时进入time-wait状态,此时TCP连接还没有释放,必须经过时间等待计时器设置的2MSL时间之后才会完全的释放。 等待2MSL的时间是为了保证最后一个连接释放报文ACK能正常的发送到服务端,最后一次ack有可能会丢失,当发生丢失的时候,服务端处于last-ack状态,收不到客户端的ack报文,服务端会超市重传第三次的连接释放报文,然后客户端会在2MSL内收到重传的释放报文,再次进行第二次ack,重新启动2MSL计时器。最后才进入close状态
      保活计时器

      在客户端进入time-wait状态后会有一个时间等待计时器,tcp还有个保活计时器,当客户端主动与服务端建立TCP连接,但是后面客户端的主机突然故障,服务器以后都不能接收到客户端发送的数据,因此需要有个措施确保服务器不要再白白的等待下去,这就是使用保活计时器。 服务器每收到一次客户的数据,就重新设置保活计时器,时间的设置通常是2小时,若俩小时内没有收到客户端的数据,服务端就发送一次探测报文段,有以后每隔75s发送一次,如果一连10次发送都没有响应,服务端就认为客户端处了故障,接着关闭TCP。

TCP流量控制与拥塞控制

流量控制

拥塞控制

TCP 输入\输出缓冲区

缓冲区

每个socket被创建后,都会分配俩个缓冲区,输入缓冲区和输出缓冲区 write\send并不直接向网络中传输数据,而是先将数据写入缓冲区中, 在由TCP协议将数据从缓冲区发送到目标机器,一旦将数据写入到缓冲区,函数就可以成功返回,不管他们有没有到达目标机器,也不管他们何时被发送到网络,这些都是TCP协议负责的事情 read\recv 函数也是如此,也从输入缓冲区中读取数据,而不是直接从网络中读取

使用write\send发送数据

使用read\recv读取数据