page contents

干货:TCP/IP协议族

TCP/IP协议族的构成 * 数据链路层:ARP,RARP* 网络层: IP,ICMP,IGMP* 传输层:TCP ,UDP,UGP* 应用层:Telnet,FTP,SMTP,SNMP,HTTP ARP和RARP 是网络层的协议,但是它所工作的内容是链路层的...

TCP/IP协议族的构成

* 数据链路层:ARP,RARP* 网络层: IP,ICMP,IGMP* 传输层:TCP ,UDP,UGP* 应用层:Telnet,FTP,SMTP,SNMP,HTTP

TCP/IP协议族

ARP和RARP 是网络层的协议,但是它所工作的内容是链路层的。。。具体来说应该是在网络层

应用层关注的是应用程序的细节,而不是数据在网络中的传输活动

其他四层用来处理所有的通信细节,对应用程序一无所知

数据链路层:

通常包括操作系统的设备驱动程序和计算机对应的网络接口,它们一起处理与电缆(或者其他任何传输媒介)的物理接口细节。主要处理有关通信媒介的细节(如以太网,令牌环网等)

ARP地址解析协议和RARP逆地址解析协议是数据链路层协议,

是某些网络接口(如以太网和令牌环网)使用的特殊协议,用来转换IP层和链路层使用的地址

网络层:

包括IP网际协议,ICMP控制报文协议,IGMP组管理协议。

其中IP提供的是不可靠的服务,他只是负责尽可能快地将分组从源节点送到目的节点。

ICMP是IP协议的附属协议,IP用ICMP来与其他主机或路由器交换错误报文和其他重要信息,虽然ICMP主要用于IP但是其他程序也可以访问ICMP

IGMP用来将一个UDP数据报多播到多个主机

传输层:

传输层主要为两台主机上的应用程序提供端到端的通信,在TCP/IP协议族中,有两个互不相同的传输协议:TCP(传输控制协议)和UDP(用户数据报协议)。TCP相对安全稳定,但是UDP速度更快。

应用层:

应用层负责处理特定的应用程序细节。几乎各种不同的TCP/IP实现都会提供下面这些通用的应用程序:

Telnet远程登陆
FTP文件传输协议
SMTP简单邮件传输协议
SNMP 简单网络管理协议


TCP协议的报文

TCP数据包的大小(TCP的首部)

TCP主机之间通过握手进程互相建立起来一种虚拟连接。在握手期间,主机之间交换序号,当数据从一台主机发送到另一台主机时序号便跟踪这些数据。

TCP把数据转换成连续的字节流,但是不能分辨出字节流的基础消息和消息边界。接收到字节流后,上层应用程序再把字节流解释成消息。

可以这么说:发送方将数据按协议封装成TCP数据包,接收方也按协议读取TCP数据包中的数据。

以太网标头

IP标头

TCP标头

TCP/IP协议族

以太网数据包的大小是固定的,1500字节的负载+22个字节的头信息=1522字节

IP数据包在以太网数据包的负载里面,它也有自己的头信息,最少需要20个字节,所以IP数据包的负载最多为1480字节

TCP数据包在IP数据包里面。除去头信息,它的最大负载时1460(但由于IP协议和TCP协议往往有额外的头信息,所以TCP实际负载为1440左右。因此,一条1500字节的信息需要两个 TCP 数据包。HTTP/2协议的一大改进就是压缩了HTTP协议的头信息,使得一个HTTP请求可以放在一个TCP数据包里,而不是分成多个,这样就提高了速度)

下图是TCP首部的数据结构

TCP/IP协议族

TCP首部的6个标志位

URG:紧急指针有效标志位,当它被置为1时,紧急指针才有效。
ACK:确认序号有效,当它被置为1时,确认序号才有效。
PSH:接受方应该尽快将这个报文交给应用层。
RST:重建连接。
SYN:同步序号用来发起一个新连接。
FIN:发端完成发送任务。

TCP数据包的编号(SEQ)

一个包1400字节,那么一次性发送大量数据,就必须分成多个包。比如,一个 10MB 的文件,需要发送7100多个包。

发送的时候,TCP 协议为每个包编号(sequence number,简称 SEQ),以便接收的一方按照顺序还原。万一发生丢包,也可以知道丢失的是哪一个包。

第一个包的编号是一个随机数。为了便于理解,这里就把它称为1号包。假定这个包的负载长度是100字节,那么可以推算出下一个包的编号应该是101。这就是说,每个数据包都可以得到两个编号:自身的编号,以及下一个包的编号。接收方由此知道,应该按照什么顺序将它们还原成原始文件。

TCP/IP协议族

(图片说明:当前包的编号是45943,下一个数据包的编号是46183,由此可知,这个包的负载是240字节。)

TCP数据包的组装

收到 TCP 数据包以后,组装还原是操作系统完成的。应用程序不会直接处理 TCP 数据包。

对于应用程序来说,不用关心数据通信的细节。除非线路异常,收到的总是完整的数据。应用程序需要的数据放在 TCP 数据包里面,有自己的格式(比如 HTTP 协议)。

TCP 并没有提供任何机制,表示原始文件的大小,这由应用层的协议来规定。比如,HTTP 协议就有一个头信息Content-Length,表示信息体的大小。对于操作系统来说,就是持续地接收 TCP 数据包,将它们按照顺序组装好,一个包都不少。

操作系统不会去处理 TCP 数据包里面的数据。一旦组装好 TCP 数据包,就把它们转交给应用程序。TCP 数据包里面有一个端口(port)参数,就是用来指定转交给监听该端口的应用程序。

TCP/IP协议族

(图片说明:系统根据 TCP 数据包里面的端口,将组装好的数据转交给相应的应用程序。上图中,21端口是 FTP 服务器,25端口是 SMTP 服务,80端口是 Web 服务器。)

应用程序收到组装好的原始数据,以浏览器为例,就会根据 HTTP 协议的Content-Length字段正确读出一段段的数据。这也意味着,一次 TCP 通信可以包括多个 HTTP 通信。


TCP握手(三次连接,四次断开)

三次握手的目的是什么,都实现了什么功能?

TCP面向连接的传输是以两个主机间的握手开始的,一个主机发送到另一个主机之间的握手有三个作用:

  • 确保目标主机可用,

  • 且目标主机正在侦听目标端口号,

  • 通知给目的主机发出者的序号,使双方在传输数据时可以进行跟踪。

这三点作用,也正是三次连接的过程,也就是目的

三次连接的过程

第一步建立连接,后两步都是确认,但是第二次握手是收到SYN包,发送SYN+ACK包,第三次握手是收到第二次握手的SYN+ACK包,发送ACK包

  • 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。

  • 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

  • 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

三次握手_百度百科

TCP3次握手连接协议和4次握手断开连接协议 - Lostyears的专栏 - CSDN博客

四次断开的过程

为什么建立连接要三次握手,而终止连接就要进行四次呢?

只是因为TCP连接是全双工的,即数据可在两个方向上同时传递,所以关闭时每个方向上都要单独关闭,这种单方向的关闭就叫半关闭。

这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的连接请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可能未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。


TCP保证网络通信可靠性的方法?

TCP为了实现网络通信的可靠性使用了复杂的拥塞控制算法,建立了繁琐的握手过程 以及重传策略。

由于TCP内置在系统协议栈中,极难对其进行改进。

拥塞控制算法

拥塞避免

为了防止cwnd增加过快而导致网络拥塞,所以需要设置一个慢开始门限ssthresh状态变量(我也不知道这个到底是什么,就认为他是一个拥塞控制的标识),它的用法:

 1. 当cwnd > ssthresh,使用慢启动算法, 2. 当cwnd < ssthresh,使用拥塞控制算法,停用慢启动算法。 3. 当cwnd = ssthresh,这两个算法都可以。

慢启动机制和ACK机制

服务器发送数据包,当然越快越好,最好一次性全发出去。但是,发得太快,就有可能丢包。带宽小、路由器过热、缓存溢出等许多因素都会导致丢包。线路不好的话,发得越快,丢得越多。

最理想的状态是,在线路允许的情况下,达到最高速率。但是我们怎么知道,对方线路的理想速率是多少呢?答案就是慢慢试。

TCP 协议为了做到效率与可靠性的统一,设计了一个慢启动(slow start)机制。开始的时候,发送得较慢,然后根据丢包的情况,调整速率:如果不丢包,就加快发送速度;如果丢包,就降低发送速度。

Linux 内核里面设定了(常量TCP_INIT_CWND),刚开始通信的时候,发送方一次性发送10个数据包,即"发送窗口"的大小为10。然后停下来,等待接收方的确认,再继续发送。

默认情况下,接收方每收到两个 TCP 数据包,就要发送一个确认消息。"确认"的英语是 acknowledgement,所以这个确认消息就简称 ACK。

ACK 携带两个信息。

 期待要收到下一个数据包的编号
接收方的接收窗口的剩余容量

发送方有了这两个信息,再加上自己已经发出的数据包的最新编号,就会推测出接收方大概的接收速度,从而降低或增加发送速率。这被称为"发送窗口",这个窗口的大小是可变的。

TCP/IP协议族

(图片说明:每个 ACK 都带有下一个数据包的编号,以及接收窗口的剩余容量。双方都会发送 ACK。)

注意,由于 TCP 通信是双向的,所以双方都需要发送 ACK。两方的窗口大小,很可能是不一样的。而且 ACK 只是很简单的几个字段,通常与数据合并在一个数据包里面发送。

TCP/IP协议族

TCP/IP协议族

(图片说明:上图一共4次通信。第一次通信,A 主机发给B 主机的数据包编号是1,长度是100字节,因此第二次通信 B 主机的 ACK 编号是 1 + 100 = 101,第三次通信 A 主机的数据包编号也是 101。同理,第二次通信 B 主机发给 A 主机的数据包编号是1,长度是200字节,因此第三次通信 A 主机的 ACK 是201,第四次通信 B 主机的数据包编号也是201。)

即使对于带宽很大、线路很好的连接,TCP 也总是从10个数据包开始慢慢试,过了一段时间以后,才达到最高的传输速率。这就是 TCP 的慢启动。

丢包处理(重传机制)

TCP 协议可以保证数据通信的完整性,这是怎么做到的?

前面说过,每一个数据包都带有下一个数据包的编号。如果下一个数据包没有收到,那么 ACK 的编号就不会发生变化。

举例来说,现在收到了4号包,但是没有收到5号包。ACK 就会记录,期待收到5号包。过了一段时间,5号包收到了,那么下一轮 ACK 会更新编号。如果5号包还是没收到,但是收到了6号包或7号包,那么 ACK 里面的编号不会变化,总是显示5号包。这会导致大量重复内容的 ACK。

如果发送方发现收到三个连续的重复 ACK,或者超时了还没有收到任何 ACK,就会确认丢包,即5号包遗失了,从而再次发送这个包。通过这种机制,TCP 保证了不会有数据包丢失。

TCP/IP协议族

(图片说明:Host B 没有收到100号数据包,会连续发出相同的 ACK,触发 Host A 重发100号数据包。)


TCP协议和UDP协议的使用场景,以及区别?

为什么UDP有时比TCP更有优势 - 野狗科技官方专栏 - SegmentFault

UDP协议的优点

能够对握手过程进行精简,减少网络通信往返次数;
能够对TLS加解密过程进行优化;
收发快速,无阻塞。

TCP和UDP的相同点?

TCP和UDP都以IP作为网络层协议,TCP和UDP的每组数据报都通过端系统和每个中间路由器中的IP层在互联网中传输

TCP和UDP的区别?

UDP是无连接协议,TCP是面向连接的协议(两个对等端内部网之间直接建立逻辑连接)(我们都说TCP是面向连接的传输协议,但是网络传输都是没有连接的,包括TCP也是一样。TCP所谓的“连接”,其实就是通讯双方维护的一个“连接状态”,让它看上去像是有连接一样。所以,TCP的状态转移是非常重要的。)

TCP比UDP安全。TCP通过跟踪数据的传送,并确认和跟踪序号来确保它成功到达接收方。(TCP为了实现网络通信的可靠性,使用了复杂的拥塞控制算法,建立了繁琐的握手过程以及重传策略。由于TCP内置在系统协议栈中,极难对其进行改进。)

相应的,UDP比TCP传输速度更快,实时性更高,网络带宽需求更小,功耗更低(虽然TCP协议中植入了各种安全保障功能,但是在实际执行的过程中会占用大量的系统开销,无疑使速度受到严重的影响。反观UDP由于排除了信息可靠传递机制,将安全和排序等功能移交给上层应用来完成,极大降低了执行时间,使速度得到了保证。 )

  • 发表于 2020-03-03 16:41
  • 阅读 ( 459 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1316 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章