上面一篇提到了互联网的产生背景,其中有一个很核心的东西是tcp/ip协议族,这个是互联网能够通信的基础。因为我们的https也是其中的一员,因此先来介绍一下tcp/ip协议族是什么东西。
一、tcp/ip模型
前面介绍了计算机通信协议是由大牛去研究并提出来的,大牛和码(ban)农(zhuan)的区别在于大牛去干之前,首先是尽可能的了解清楚,然后进行抽象建模(码农直接就是干),因此人家把提出了网络通信的tcp/ip模型,我等只会搬砖。
tcp/ip有四层结构,物理层并不在tcp/ip模型中,不过可以在ISO/OSI七层模型中找到,具体可以参考ISO/OSI七层模型介绍。每一层都有一些协议,那么为什么要这么分层呢。
首先不考虑有多少层,分层的目的在于解耦,这个和我们软件开发的原则是一致的。每一层都有各自的功能,至于每一层采用什么协议,怎么实现,其他层不需要考虑,这就保证了每一层互不影响。至于分成四层还是七层,便是仁者见仁智者见智的问题,不过四层已经成为了事实上的标准。每一层都有各自的功能。
(1). 链路层
也称作数据链路层或网络接口层(在第一个图中为网络接口层和硬件层),通常包括操作系统中的设备驱动程序和计算机中对应的网络接口卡。它们一起处理与电缆(或其他任何传输媒介)的物理接口细节。ARP(地址解析协议)和RARP(逆地址解析协议)是某些网络接口(如以太网和令牌环网)使用的特殊协议,用来转换IP层和网络接口层使用的地址。
(2). 网络层
也称作互联网层,处理分组在网络中的活动,例如分组的选路。在TCP/IP协议族中,网络层协议包括IP协议(网际协议),ICMP协议(Internet互联网控制报文协议),以及IGMP协议(Internet组管理协议)。
IP是一种网络层协议,提供的是一种不可靠的服务,它只是尽可能快地把分组从源结点送到目的结点,但是并不提供任何可靠性保证。同时被TCP和UDP使用。TCP和UDP的每组数据都通过端系统和每个中间路由器中的IP层在互联网中进行传输。
ICMP是IP协议的附属协议。IP层用它来与其他主机或路由器交换错误报文和其他重要信息。
IGMP是Internet组管理协议。它用来把一个UDP数据报多播到多个主机。
(3). 传输层
主要为两台主机上的应用程序提供端到端的通信。在TCP/IP协议族中,有两个互不相同的传输协议:TCP(传输控制协议)和UDP(用户数据报协议)。
TCP为两台主机提供高可靠性的数据通信。它所做的工作包括把应用程序交给它的数据分成合适的小块交给下面的网络层,确认接收到的分组,设置发送最后确认分组的超时时钟等。由于运输层提供了高可靠性的端到端的通信,因此应用层可以忽略所有这些细节。为了提供可靠的服务,TCP采用了超时重传、发送和接收端到端的确认分组等机制。
UDP则为应用层提供一种非常简单的服务。它只是把称作数据报的分组从一台主机发送到另一台主机,但并不保证该数据报能到达另一端。一个数据报是指从发送方传输到接收方的一个信息单元(例如,发送方指定的一定字节数的信息)。UDP协议任何必需的可靠性必须由应用层来提供。
(4). 应用层
应用层负责处理特定的应用程序细节。
下面列了每一层的一些协议
实际的协议当然远远不止以上几种,不过对于应用层开发来说,只需要了解应用层和传输层协议即可,由于Http(s)属于应用层层,通过传输层TCP协议进行连接,因此重点介绍这两个协议。
二、TCP协议
上面介绍了TCP的功能,核心特点是可靠、稳定,这也就是为什么很多应用采用TCP的原因,如果考虑到性能的问题,也可以采用UDP,那么可靠性和稳定性就需要自己来实现,包括数据检测、错误重传、流量控制等等,TCP和UDP的优缺点可以自行去整理一下,总之如果对于通信质量有要求用TCP,通信质量没有要求的话用UDP。如果接触过TCP的人,看到TCP第一眼就会想到三次握手(连接)、四次挥手(断开连接),先不急介绍这些,先来介绍TCP最基本的东西。首先是TCP协议格式。
(1)TCP协议格式
对于程序员来说,当我们要解决问题的时候,首先要确定数据结构,当制定TCP的时候,当然也需要定义TCP的协议格式。当我们自己要制定tcp协议我们会怎么做,首先将协议抽象成头部和数据,因为我们需要打包上一层的数据,因此要留一块区域给数据,其他的就是头部的内容。
头部内容要包含哪些?tcp是提供可靠和稳定的传输,需要考虑到数据的长度、校验和,数据传输是否成功要有序号和确认号,数据量比较大需要分片,考虑到性能的原因,一次不可能只发送一片,等成功之后,再发下一片,因此需要分批发送,全部成功之后,再发下一批(也可能是前几个成功,往后挪),涉及到滑动窗口概念,需要字段设置窗口大小(一批的大小,数据片到达顺序不是按照发送顺序的,对方需要对分片数据进行组装),要发送给对方,需要源目的地址、端口号和目标地址、端口号,IP协议中包含了地址字段,TCP协议只需设置端口号等等,因此最终有一下协议格式。
各字段解释如下:
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三次握手和四次挥手
tcp连接需要经过三次握手,为什么需要经过三次握手才确定已经连接,想象一个场景,你和你女朋友打电话,需要确定是否想通的,你会问“听得到吗”,你女朋友收到之后,回复“听得到”,然后问你“听得到吗”,你收到答复之后,回复“听得到”,然后就确定双方都正常通话啦。
上面的例子可以看到,通过三次确定就可以开始正常通话啦,tcp协议也是类似,通过三次确定来确定连接正常,这个过程也被称为三次握手,三次握手已经是理论上的最小确认次数。
上图是tcp的三次握手过程,为什么seq初始值要随机,而不能固定,因为如果采用固定值,第一次发送超时,再发送的话,服务端返回一个ack=seq+1,这个到底是哪次的不清楚,另一个第一次数据传输过程中,发了10个包,客户端挂了,由于路由缓存,当客户端再次连接成功,发送5个包,前面的10个包返回的seq就会导致客户端序号错乱。因此seq初始值必须是随机值。
tcp四次挥手完成断开连接操作。
tcp是全双工的连接方式,需要两端单独进行关闭。MSL是报文寿命长度,一般2min,之所以C端需要等待2个MSL,是为了确保C端发送的最后一次关闭报文能够到达S端,因为报文会丢失,S端可以在丢失之后重发,这样C端可以在2MSL时间内收到确认报文,再发送关闭报文,保证S端和C端都关闭,S端先于C端关闭。tcp除了刚才介绍的一些东西之外,还有很多比较重要的东西,比如流量控制,通过调节滑动窗口大小进行流量控制。