TCP 原理

时间:2021-11-27 08:37:51
一、分组交换网络

- 古老的电话通信,一根电缆,两个用户设备通信
![](https://img2018.cnblogs.com/blog/1226829/201810/1226829-20181008213243720-379255914.png)

  • 计算机中的两个设备节点通信:分组网络

    TCP 原理

计算机网络采取分组交换技术,意思就是我有【一块数据】要发给对方,那我会把这【一块数据】分成N份【单位数据】,分别发出去,而每份【单位数据】走哪条路是不一定的,但是这些【单位数据】总要全部达到对方手里,对方再根据【单位数据】里记录的序号拼接起来,组成完整的【一块数据】。这就是分组的意思所在。

基本TCP通信原理就这样

 

二、TCP数据报

![](https://img2018.cnblogs.com/blog/1226829/201810/1226829-20181008214056532-532264164.png)

  1. 端口号:用来标识同一台计算机的不同的应用进程。

     

    1)源端口:源端口和IP地址的作用是标识报文的返回地址。

     

    2)目的端口:端口指明接收方计算机上的应用程序接口。

     

    TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接。

  2. 序号和确认号:是TCP可靠传输的关键部分。序号是本报文段发送的数据组的第一个字节的序号。在TCP传送的流中,每一个字节一个序号。e.g.一个报文段的序号为300,此报文段数据部分共有100字节,则下一个报文段的序号为400。所以序号确保了TCP传输的有序性。确认号,即ACK,指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK标志为1时才有效。比如建立连接时,SYN报文的ACK标志位为0。

  3. 数据偏移/首部长度:4bits。由于首部可能含有可选项内容,因此TCP报头的长度是不确定的,报头不包含任何任选字段则长度为20字节,4位首部长度字段所能表示的最大值为1111,转化为10进制为15,15*32/8 = 60,故报头最大长度为60字节。首部长度也叫数据偏移,是因为首部长度实际上指示了数据区在报文段中的起始偏移值。

  4. 保留:为将来定义新的用途保留,现在一般置0。

  5. 控制位:URG ACK PSH RST SYN FIN,共6个,每一个标志位表示一个控制功能。

     

    1)URG:紧急指针标志,为1时表示紧急指针有效,为0则忽略紧急指针。

     

    2)ACK:确认序号标志,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段。

     

    3)PSH:push标志,为1表示是带有push标志的数据,指示接收方在接收到该报文段以后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队。

     

    4)RST:重置连接标志,用于重置由于主机崩溃或其他原因而出现错误的连接。或者用于拒绝非法的报文段和拒绝连接请求。

     

    5)SYN:同步序号,用于建立连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1。

     

    6)FIN:finish标志,用于释放连接,为1时表示发送方已经没有数据发送了,即关闭本方数据流。

  6. 窗口:滑动窗口大小,用来告知发送端接受端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。窗口大小时一个16bit字段,因而窗口大小最大为65535。

  7. 校验和:奇偶校验,此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得。由发送端计算和存储,并由接收端进行验证。

  8. 紧急指针:只有当 URG 标志置 1 时紧急指针才有效。紧急指针是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。 TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式。

  9. 选项和填充:最常见的可选字段是最长报文大小,又称为MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。

  10. 数据部分: TCP 报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。

参考文章:请点击

 

三、TCP的可靠原理

UDP为不可靠数据服务,不保证数据报能到达对方,可能丢包;而TCP的可靠是相对UDP的,另外处于传输层之下的IP层也是不可靠的,仅提供尽力而为的端到端数据传输服务(best-effort delivery service),不作任何保证。所以TCP的可靠性是指基于不可靠的IP层在传输层提供可靠的数据传输服务,主要是指传输数据不会损坏或丢失,而且所有数据都是按照发送顺序进行传送。实现TCP的可靠传输有以下机制:

  1. 校验和(校验数据是否损坏)

  2. 定时器(分组丢失则重传)

  3. 序号(用于检测丢失的分组和冗余的分组)

  4. 确认(接收方告知发送方正确接收分组以及期望的下一个分组)

  5. 否定确认(接收方通知发送方未被正确接收的分组)

  6. 窗口和流水线(用于增加信道的吞吐量)

至于数据是否在中途被修改或者被窃听,这应该是属于安全性问题。提高安全性最根本的办法就是加密数据,比如远程登录用ssh而非telnet。

TCP只能保证数据的完整性,不能保证安全性

要保证安全性只能依靠:MD5/SHA 的哈希算法,进行数字签名。

 

3.2 数据校验和重传

每个Tcp连接在内核中都有一个发送缓冲区和一个接收缓冲区。tcp协议要求对方在接受到tcp数据报之后,要对其该数据包序号进行ACK应答(ack=该数据包序号),只有当接受到一个tcp数据报的ACK之后,才可以把这个tcp数据报从socket的发送缓冲区清除,另外tcp还有一个流量控制功能,tcp的socket接受缓冲区接受到网络上来的数据缓存起来后,如果应用程序一直没有读取,

socket接收缓冲区满了之后,发生的动作是:通知对端TCP协议中的窗口关闭,这便是滑动窗口的实现,保证TCP socket接收缓冲区不会溢出,因为对方不允许发送超过所通知窗口大小的数据, 这就是TCP的流量控制,如果对方无视窗口大小而发出了超过窗口大小的数据,则接收方TCP将丢弃它。这两点保证了tcp是可靠传输的。

也可以这么回答

  1. 对数据块分包序号,编号。确保完整

  2. 接收端确认和重传机制,对每个数据包都要 ACK=该包序号,确认收到

  3. 数据校验,对数据长度简单校验,无法确保安全,只能确保可靠

  4. 流量控制

  5. 拥塞控制

重传可能原因:

1.、在中间节点丢了。2、还在路上,走的慢。3、接收端的ACK确认报文在传输中途丢失。 4、接收端异常未响应ACK或被接收端丢弃

重传原理参考本文

重传原理参考本2

两次duplicated ACK肯定是乱序造成的!
丢包肯定会造成三次duplicated ACK! 假定通信双方如下,A发送4个TCP Segment 给B,编号如下,N-1成功到达,因为A收到B的
ACK(N),其它按照到达顺序,分别收到ACK(N)的数目:
A ---------> B A方发送顺序N-1,N,N+1,N+2 B方到达顺序 N-1,N,N+1,N+2
A收到1个ACK (N) N-1,N,N+2,N+1
A收到1个ACK (N) N-1,N+1,N,N+2 (接收方乱序)
A收到2个ACK (N) N-1,N+1,N+2,N
A收到3个ACK (N) N-1,N+2,N,N+1
A收到2个ACK (N) N-1,N+2,N+1,N
A收到3个ACK (N) 如果N丢了,没有到达B N-1,N+1,N+2
A收到3个ACK (N) N-1,N+2,N+1
A收到3个ACK (N) TCP segment 乱序 有2/5 = 40% 的概率会造成A收到三次 duplicated ACK(N);
而如果N丢了,则会100%概率A会收到三次duplicated ACK(N); 基于以上的统计,当A接收到三次 duplicated ACK(N)启动 Fast Retransmit 算法是合理的,即立
马retransmit N,可以起到Fast Recovery的功效,快速修复一个丢包对TCP管道的恶劣影响。 而如果A接收到二次 duplicated ACK(N),则一定说明是乱序造成的,即然是乱序,说明 数据都到
达了B,B的TCP负责重新排序而已,没有必要A再来启动Fast Retransmit算法

 

UDP 不可靠原理(丢包原理之一)

UDP只有一个socket接收缓冲区,没有socket发送缓冲区,即只要有数据就发,不管对方是否可以正确接受。而在对方的socket接受缓冲区满了之后,新来的数据报无法进入到socket接受缓冲区,此数据报就会被丢弃,udp是没有流量控制的,故UDP的数据传输是不可靠的。