TCP/IP是一个庞大的协议族,它是众多网络协议的集合,包括:ARP、IP、ICMP、UDP、TCP、DNS、DHCP、HTTP、FTP、MQTT等等。这些协议按照功能,可以被划分为几个不同的层次,如图所示:

应用层:OSI参考模型的第七层,其作用是通过应用程序间的交互来完成特定的网络应用。定义了应用进程之间的交互规则,通过不同的应用层协议为不同的网络应用提供服务。应用层交互的数据单元我们称之为报文
表示层:使通信的应用程序能够解释交换数据的含义,其位于 OSI参考模型的第六层,向上为应用层提供服务,向下接收来自会话层的服务该层提供的服务主要包括数据压缩,数据加密以及数据描述,使应用程序不必担心在各台计算机中表示和存储的内部格式差异
会话层:会话层就是负责建立、管理和终止表示层实体之间的通信会话,该层提供了数据交换的定界和同步功能,包括了建立检查点和恢复方案的方法
传输层:为两台主机进程之间的通信提供服务,处理数据包错误、数据包次序,以及其他一些关键传输问题,传输层向高层屏蔽了下层数据通信的细节。因此,它是计算机通信体系结构中关键的一层。其中,主要的传输层协议是TCP和UDP
网络层:两台计算机之间传送数据时其通信链路往往不止一条,所传输的信息甚至可能经过很多通信子网。网络层的主要任务就是选择合适的网间路由和交换节点,确保数据按时成功传送,发送数据时,网络层把传输层产生的报文或用户数据报封装成分组和包,向下传输到数据链路层。网络层使用的协议是无连接的网际协议(Internet Protocol)和许多路由协议,因此我们通常把该层简单地称为 IP 层
数据链路层:也叫做链路层,在物理层和网络层之间。两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层协议。在两个相邻节点之间传送数据时,数据链路层将网络层交下来的 IP数据报组装成帧,在两个相邻节点间的链路上传送帧。每一帧的数据可以分成:报头head和数据data两部分:
通过控制信息我们可以知道一个帧的起止比特位置,此外,也能使接收端检测出所收到的帧有无差错,如果发现差错,数据链路层能够简单的丢弃掉这个帧,以避免继续占用网络资源
物理层:作为OSI 参考模型中最低的一层,物理层的作用是实现计算机节点之间比特流的透明传送该层的主要任务是确定与传输媒体的接口的一些特性(机械特性、电气特性、功能特性,过程特性)该层主要是和硬件有关,与软件关系不大


IP协议(Internet Protocol),又称网际协议,协议处于IP层工作,是整个协议栈的核心协议,上层协议都依赖IP协议提供的服务,IP协议负责将数据报从源主机发送到目标主机,通过IP地址作为唯一识别码,在发送数据报的过程中,IP协议还可能对数据报进行分片处理,同时在接收数据报的时候还可能需要对分片的数据报进行重装等等。
IP协议是一种无连接的不可靠数据报交付协议,协议本身不提供任何的错误检查与恢复机制。
在TCP/IP设计之初,为了标识互联网中的每台主机的身份,设计人员为每个接入网络中的主机都分配一个IP地址(Internet Protocol Address),是一个32位的整数地址,只有合法的IP地址才能接入互联网中并且与其他主机进行通信,IP地址是软件地址,不是硬件地址,硬件MAC地址是存储在网卡中的,应用于本地网络中寻找目标主机。而IP地址能让一个网络中的主机能够与另一个网络中的主机进行通信,无需理会这些主机之间的MAC地址。
每个IP地址长度为32比特(4字节),因此总共有2^32个可能的IP地址,大约有40亿个IP地址能被使用的。这些地址一般按所谓点分十进制记法(dotted-decimal notation)书写,即地址中的每个字节用它的十进制形式书写,各字节间以点分隔开。例如, IP地址为192.168.0.122,192是该地址第一个8比特的十进制等价数,168是该地址第二个8比特的十进制等价数,依次类推。
互联网中,每个主机都有唯一的一个IP地址作为身份识别,每个主机的IP地址的一部分都由其所在的子网决定的,所以出现了IP地址分类编址的概念,网络的类型决定了IP 地址将如何划分成网络部分和节点部分,在分类编址中,设计者把所有的IP地址划分为5大类,分别为A、B、C、D、E五类,每一类地址都觉定了其中IP地址的一部分组成,具体见:

| 类别 | 第一字节(二进制) | 第一字节取值范围 | 网络号个数 | 主机号个数 | 适用范围 |
|---|---|---|---|---|---|
| A类 | 0XXX XXXX | 0~127 | 125 | 16777214 | 大型网络 |
| B类 | 10XX XXXX | 128~191 | 16368 | 65534 | 中型网络 |
| C类 | 110X XXXX | 192~223 | 2097152 | 254 | 小型网络 |
| D类 | 1110 XXXX | 224~239 | — | — | 多播 |
| E类 | 1111 XXXX | 240~255 | — | — | 保留 |
除了上述的网络地址外,还有一些特殊用途的地址,这些地址是不允许分配给任何一个网络的主机使用的
广播通信是一对所有的通信方式,受限广播地址用于定义整个互联网,如果设备想使IP数据报被整个网络所接收,就发送这个目的地址全为1的广播包,这样会给整个互联网带来灾难性的负担,所以在任何情况下,路由器都会禁止转发目的地址为255.255.255.255的广播数据包,这样的数据包仅会出现在本地网络中(局域网),255.255.255.255这个地址指本网段内的所有主机。注意:此处不要与以太网的广播地址(255-255-255-255-255-255)混淆了。受限广播地址是网络号与主机号都为1的地址,
直接广播地址是主机号全为1而得到的地址,广播地址代表本网络内的所有主机,使用该地址可以向网络内的所有主机发送数据,比如一个IP地址是192.168.0.181,这是C类地址,所以它的主机号只有一个字节,那么对主机号全取1得到一个广播地址192.168.0.255,向这个地址发送数据就能让同一网络下的所有主机接收到。
另外,直接广播地址使一个网段中可分配给设备的地址数减少了1个。
多播地址用在一对多的通信中,即一个发送者,多个接收者,不论接受者员数量的多少,发送者只发送一次数据包。多播地址属于分类编址中的D类地址, D类地址只能用作目的地址,而不能作为主机中的源地址。
127网段的所有地址都称为环回地址,用来测试网络协议是否工作正常。比如ping 127.1.1.1就可以测试本地TCP/IP协议是否正常。不能以127网段中的IP地址作为主机地址,因此A类地址又少了一个可用网络号。
IP地址32bit全为0的地址(0.0.0.0)表示的是本网络本主机,这个IP地址在IP数据报中只能用作源IP地址,这发生在当设备启动时但又不知道自己的IP地址情况下。在使用DHCP分配IP地址的网络环境中,这样的地址是很常见的,主机为了获得一个可用的IP地址,就给DHCP服务器发送IP数据报,并用这样的地址(0.0.0.0)作为源地址,目的地址为255.255.255.255(因为主机这时还不知道DHCP服务器的IP地址),然后DHCP服务器就会知道这个主机暂时没有IP地址,那么就会分配一个IP给这个主机。
UDP协议的特点:
UDP虽然有很多缺点,但它的实时性非常好,用于实时视频的传输,比如直播、网络电话等,因为即使是出现了数据丢失的情况,导致视频卡帧,这也不是什么大不了的事情,所以,UDP协议还是会被应用与对传输速度有要求,并且可以容忍出现差错的数据传输中。
TCP与UDP一样,都是传输层的协议,但是提供的服务却大不相同,UDP为上层应用提供的是一种不可靠的,无连接的服务,而TCP则提供一种面向连接、可靠的字节流传输服务,TCP让两个主机建立连接的关系,应用数据以数据流的形式进行传输,这与UDP协议是不一样:
连接机制:TCP是一个面向连接的协议,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一个连接,否则将无法发送数据,一个TCP连接必须有双方IP地址与端口号。
确认与重传:一个完整的TCP传输必须有数据交互,接收方在接收到数据之后必须正面进行确认,向发送方报告接收的结果,而发送方在发送数据之后必须等待接收方的确认,同时发送的时候会启动一个定时器,在指定超时时间内没收到确认,发送方就会认为发送失败,然后进行重发操作,这就是重传报文。
TCP提供可靠的运输层,但它依赖的是IP层的服务,IP数据报的传输是无连接、不可靠的,因此它要通过确认来知道接收方确实已经收到数据了。但数据和确认都有可能会丢失,因此TCP通过在发送时设置一个超时机制(定时器)来解决这种问题,如果当超时时间到达的时候还没有收到对方的确认,它就重传该数据。
缓冲机制:在发送方发送数据的时,由于应用程序的数据大小、类型不可预估,TCP协议提供了缓冲机制来处理这些数据,如在数据量很小的时候,TCP会将数据存储在一个缓冲空间中,等到数据量足够大的时候在进行发送数据,这样子能提供传输的效率并且减少网络中的通信量,而且在数据发送出去的时候并不会立即删除数据,还是让数据保存在缓冲区中,因为发送出去的数据不一定能被接收方正确接收,它需要等待到接收方的确认再将数据删除。同样的,在接收方也需要有同样的缓冲机制,因为在网络中传输的数据报到达的时间是不一样的,而且TCP协议还需要把这些数据报组装成完整的数据,然后再递交到应用层中。
全双工通信:TCP连接建立后,两个主机就对等,任何一个主机都可以向另一个主机发送数据,数据是双向流通的,所以TCP协议是一个全双工的协议,这种机制为TCP协议传输数据带来很大的方便。
流量控制:TCP提供了流量控制服务(flow-control service)以消除发送方使接收方缓冲区溢出的可能性。流量控制是一个速度匹配服务,即发送方的发送速率与接收方应用程序的读取速率相匹配,TCP通过让发送方维护一个称为接收窗口(receive window)的变量来提供流量控制,它用于给发送方一个指示:接收方还能接收多少数据,接收方会将此窗口值放在 TCP 报文的首部中的窗口字段,然后传递给发送方,这个窗口的大小是在发送数据的时候动态调整的。
差错控制:除了确认与重传之外,TCP协议也会采用校验和的方式来检验数据的有效性,主机在接收数据的时候,会将重复的报文丢弃,将乱序的报文重组,发现某段报文丢失了会请求发送方进行重发,因此在TCP往上层协议递交的数据是顺序的、无差错的完整数据。
拥塞控制:当数据从一个大的管道(如一个快速局域网)向一个较小的管道(如一个较慢的广域网)发送时便会发生拥塞。当多个输入流到达一个路由器,而路由器的输出流小于这些输入流的总和时也会发生拥塞,这种是网络状况的原因。 如果一个主机还是以很大的流量给另一个主机发送数据,但是其中间的路由器通道很小,无法承受这样大的数据流量的时候,就会导致拥塞的发生,这样子就导致了接收方无法在超时时间内完成接收(接收方此时完全有能力处理大量数据),而发送方又进行重传,这样子就导致了链路上的更加拥塞,延迟发送方必须实现一直自适应的机制,在网络中拥塞的情况下调整自身的发送速度,这种形式对发送方的控制被称为拥塞控制(congestion control),与前面我们说的流量控制是非常相似的,而且TCP协议采取的措施也非常相似,均是限制发送方的发送速度。
TCP协议的连接是包括上层应用间的连接,简单来说,TCP连接是两个不同主机的应用连接,而传输层与上层协议是通过端口号进行识别的,如IP协议中以IP地址作为识别一样,端口号的取值范围是0~65535,这些端口标识着上层应用的不同线程。
| 端口号 | 协议 | 说明 |
|---|---|---|
| 20/21 | FTP | 文件传输协议,使得主机间可以共享文件。 |
| 23 | Telnet | 终端远程登录,它为用户提供了在本地计算机上完成远程主机工作的能力。 |
| 25 | SMTP | 简单邮件传输协议,它帮助每台计算机在发送或中转信件时找到下一个目的地。 |
| 69 | TFTP | 普通文件传输协议。 |
| 80 | HTTP | 超文本传输协议,通过使用网页浏览器、网络爬虫或者其它的工具,客户端发起一个HTTP请求到服务器上指定端口(默认端口为80),应答的服务器上存储着一些资源,比如HTML文件和图像,那么就会返回这些数据到客户端。 |
| 110 | POP3 | 邮局协议版本3,本协议主要用于支持使用客户端远程管理在服务器上的电子邮件。 |
TCP报文段由 首部 + 数据区域 组成,TCP报文段的首部我们称之为TCP首部,其首部内容很丰富,各个字段都有不一样的含义,如果不计算选项字段,一般来说TCP首部只有20个字节,具体见图:

当建立一个新的连接时,TCP报文段首部的 SYN标志变1,序号字段包含由这个主机随机选择的初始序号ISN(Initial Sequence Number)。该主机发送数据的第一个字节序号为 ISN+1,因为SYN标志会占用一个序号。
TCP协议给每个传输的字节都了编号,那么确认序号就包含接收端所期望收到的下一个序号,因此,确认序号应当是上次已成功收到数据的最后一个字节序号加1。当然,只有ACK标志为1时确认序号字段才有效,TCP为应用层提供全双工服务,这意味数据能在两个方向上独立地进行传输,因此确认序号通常会与反向数据(即接收端传输给发送端的数据)封装在同一个报文中(即捎带),所以连接的每一端都必须保持每个方向上的传输数据序号准确性。
首部长度字段占据4bit空间,它指出了TCP报文段首部长度,以字节为单位,最大能记录15*4=60字节的首部长度,因此,TCP报文段首部最大长度为60字节。在字段后接下来有6bit空间是保留未用的。
此外还有6bit空间,是TCP报文段首部的标志字段,用于标志一些信息:
TCP是一个面向连接的协议,发送数据之前,都必须先在双方之间建立一条连接,俗称“握手”。
“三次握手”建立连接:
建立连接的过程是由客户端发起,而服务器等待着客户端的连接,TCP连接一般来说会经历以下过程:

客户端P首先向服务器发送一个特殊的TCP报文段:不包含应用层数据,但是在报文段的首部中的SYN标志位会被置为1被称为SYN报文段。另外,客户会随机地选择一个初始序号(ISN,假设为A),并将此序号放置于该SYN报文段的序号字段中;但SYN报文段中的ACK标志位0,此时它的确认序号段是无效的。该报文段会被封装在一个IP数据报中,然后发送给目标服务器。
服务器收到客户端发出的SYN报文段,便会从SYN报文段中提取对应的信息,为该TCP连接分配TCP缓存和变量,并向该客户TCP发送允许连接的报文段(握手应答报文)。这个报文段同样也不包含任何应用层数据,但是,在报文段的首部却包含3个重要的信息。
允许连接的报文段实际上表明了:“我收到了你发起建立连接的请求,初始序号为A,我同意建立该TCP连接,我自己的初始序号是B。”该允许连接的报文段有时被称为SYN ACK报文段(SYN ACK segment),同时由于ACK标志位1,所以TCP报文段首部的窗口大小字段是有效的。
当客户端收到服务器的握手应答报文后,会将ACK标志置位,此时客户端的TCP报文段的 ACK标志被设置为1,而对于SYN标志,因为连接已经建立了,所以该标志会被置为0,同时客户端也要给该TCP连接分配缓存和变量,并且客户端还需要返回一个应答报文段,这个报文对服务器的应答报文段作出应答,将TCP报文段首部的确认序号字段设置为B+1,同时也会告知服务器的窗口大小。
终止一个连接要经过四次挥手,因为 TCP连接是全双工连接,因此每个方向上的连接必须单独关闭。当一端完成数据发送任务后就能发送一个FIN报文段(可以称之为终止连接请求,其实就是FIN标志位被设置为1)来终止这个方向上的连接。另一端收到一个 FIN报文段,它必须通知应用层对方终止了那个方向的连接,发送FIN报文段通常是应用层进行关闭的结果。
注意了:客户端发送一个FIN报文段只意味着在这一方向上没有数据流动,一个 TCP连接在发送一个 FIN后仍能接收数据,但是在实际应用中只有很少的 TCP应用程序这样做。
“四次挥手”终止连接具体过程如下:

TCP协议根据连接时接收到报文的不同类型,采取相应动作也不同,还要处理各个状态的关系,如当收到握手报文时候、超时的时候、用户主动关闭的时候等都需要不一样的状态去采取不一样的处理。
TCP协议的状态如下:

对图中的补充说明(很重要,要牢牢记住):
三次握手过程:
四次挥手过程:
{客户端->服务器} 方向上的连接已经断开。{客户端->服务器} 方向上的连接,因此服务器的原因程序会主动关闭该方向上的连接,发送一个FIN报文段给客户端。{客户端->服务器} 方向上的连接已经终止,进入CLOSED状态。