【TCP/IP网络编程】:05TCP原理 --简单描述

本篇文章主要对TCP原理进行简单的分析和讨论。

TCP套接字中的I/O缓冲

前文有介绍过TCP通信数据无边界的特性,即本端一次发送的数据对端并不一定一次性接收,那剩余的数据在哪里呢?

实际上,write函数调用后并非立即传输数据,read函数调用后也并非马上接收数据。如下图所示,write函数调用瞬间,数据将移至输出缓冲区(适当的时侯传向对方的输入缓冲);read函数调用瞬间,从输入缓冲区读取数据。

 TCP套接字的I/O缓冲

 TCP的I/O缓冲有如下特点:

  • I/O缓冲在每个TCP套接字中单独存在
  • I/O缓冲在创建TCP套接字时自动生成
  • 即使关闭套接字也会继续传输发送缓冲区中遗留的数据
  • 关闭套接字将丢弃输入缓冲区中的数据

考虑这样一种情况,接收端输入缓冲区大小为50字节,而发送端输出缓冲大小为100字节,当发送端向接收端传输100字节的数据时会发生什么呢?接收端缓冲区溢出?其实,接收端可以正常处理这种情况,因为TCP会控制数据流(Flow Control),这是由TCP协议的滑动窗口(Sliding Window)机制来保证的。

关于数据交换时调用的函数write和read(阻塞模式下),write函数调用的返回时机是发送端将数据传输至输出缓冲区;read函数的返回时机是接收缓冲区有数据待读取时。

TCP内部工作原理1:与对方套接字的连接

 TCP连接的分组交换

TCP状态转换图(取自UNP,算是进阶点的内容,画质不好,先凑合看吧,抽空重新画下)

整体来看,TCP套接字从创建到消失所经历的过程如下:

  • 与对方套接字建立连接
  • 与对方套接字进行数据交换
  • 断开与对方套接字的连接

关于TCP套接字建立连接的过程如下图所示,该过程就是所谓的三次握手(Three-way handshaking)机制。

 TCP套接字连接过程

[SYN] SEQ:1000,ACK:-

首次建立连接请求时使用的消息字段为SYN(Synchronization),即收发数据前传输的同步消息。SEQ值1000表示该数据包的编号,ACK字段为空。

[SYN+ACK] SEQ:2000,ACK:1001

ACK是向对端的反馈字段,值1001表示已收到对端编号为1000的消息。

通过数据包编号并确认的方式,可以在数据丢失时马上查看并重传丢失的数据包,这也是TCP消息可靠的原因。

关于三次握手中主机A最后一次ACK消息的讨论,若该数据包丢失会发生什么?

若最后的ACK消息丢失,服务器端(主机B)并不会重传SYN+ACK消息,而是直接发送RST报文进入closed状态,目的是为了防止SYN泛洪攻击;另一个考虑,若最初客户端主机A的SYN消息受网络阻塞很久才到达服务器端,而客户端由于长久未与服务端建立连接而关闭了套接字,则此时服务器端也不能收到ACK消息的回应,因此也就没必要重发SYN+ACK消息。

TCP内部工作原理2:与对方主机的数据交换

三次握手后双方便建立了有效的连接,接下来是数据交换的过程,如下图所示。

 TCP套接字数据交换过程

以上通信过程的消息字段和三次握手过程一样,需要注意的是ACK消息字段的值是这样计算的:SEQ值 + 传递的字节数 + 1。加1是为了告知对方之前发送的消息已全部接收,下次可发送其余数据。如果数据包发生丢失又会怎样?

 TCP套接字数据传输错误处理

如上图示过程,为了完成数据包重传,TCP套接字启动计时器以等待ACK应答。若相应计时器发生超时(Time-out)则重传。

TCP内部工作原理3:断开与套接字的连接

TCP套接字的结束过程也非常优雅。如果对方还有数据需要传输时直接断连会出问题,所以断连时需要双方协商。该过程如下图所示,也即四次握手(Four-way handshaking)断开连接的过程。

 TCP套接字断开连接过程

携带有FIN字段的数据包表示断开连接,也就是说,双方各发送一次FIN消息后断开连接。

posted @ 2019-12-22 22:52  gloryd  阅读(464)  评论(0编辑  收藏  举报
levels of contents