传输控制协议(TCP协议)是一种面向连接的、可靠的、基于字节流的方式进行有序的无差错的数据传输通讯协议,它负责完成传输层所指定的功能,利用重发技术和拥塞控制机制,向应用程序提供可靠的通信连接,使它能够自动适应网上的各种变化。比如:数据报检测、流量控制、拥塞控制、数据排序、超时重发等。
1.1网络分层模型
OSI:Open System Interconnection,开放式系统互联国际标准化组织(ISO)制定的理论模型。
各层含义:
应用层:是为计算机用户提供应用接口,也为用户直接提供各种网络服务。我们常见应用层的网络服务协议有:HTTP,HTTPS,FTP,POP3、SMTP等。
表示层:提供各种用于应用层数据的编码和转换功能,确保一个系统的应用层发送的数据能被另一个系统的应用层识别。
会话层:就是负责建立、管理和终止表示层实体之间的通信会话。该层的通信由不同设备中的应用程序之间的服务请求和响应组成。
传输层:传输层建立了主机端到端的链接,传输层的作用是为上层协议提供端到端的可靠和透明的数据传输服务。
网络层:本层通过IP寻址来建立两个节点之间的连接,为源端的运输层送来的分组,选择合适的路由和交换节点,正确无误地按照地址传送给目的端的运输层。就是通常说的IP层。这一层就是我们经常说的IP协议层。
数据链路层:将比特组合成字节,再将字节组合成帧,使用链路层地址(以太网使用MAC地址)来访问介质,并进行差错检测。
物理层:实际最终信号的传输是通过物理层实现的。通过物理介质传输比特流。
1.2 TCP报文中的字段
序号(sequencenumber):用来标识从源端到目的端发送的字节流,发起方发送数据时对此进行标记,比如:一个报文段的序号为100,此报文段数据部分共有200字节,则下一个报文段序号为300
确认号(acknowledgement number):指明下一个期待收到的字节序号,只有ACK标志位为1时确认序号字段才有效,ack = seq+1
1.3标志位:
①URG:紧急指针标志,为1时表示紧急指针有效。
②ACK:确认序号标志,ACK=1时表示有效。只有当ACK=1时,前面的确认号字段才有效,TCP连接建立后,ACK必须为1。
③PSH:表示接收方在收到该报文段后应尽快将该报文段交给应用程序。
④RST:当RST=1时说明TCP连接出现了错误(如主机崩溃),必须释放连接后再重新建立连接,或者用于拒绝非法的报文段和拒绝连接请求。
⑤SYN:发起新连接,当SYN=1,表示这是一个请求建立连接的报文段;当SYN=1,ACK=1时,表示对方同意建立连接,只有在前两次握手中SYN才为1。
⑥FIN:用于释放连接,FIN=1表示数据已经发送完成,可以释放连接。
1.4 TCP三次握手
在TCP建立连接的过程中,必定由一方主动发起,另一方被动接收,下图为客户端主动发起的图解:
首先主动打开连接的客户端结束CLOSED状态,被动打开的服务器端也结束CLOSED状态,并进入LISTEN状态。随后开始“三次握手”:
①客户端向服务端发送一段TCP报文:
标志位为SYN=1,表示“请求建立新连接”;序号为seq=x(x通常为1);随后客户端进入SYN-SENT状态
②服务端接收到来自客户端的TCP报文之后,结束LISTEN状态,并返回一段TCP报文:
标志位为SYN=1,ACK=1,表示“已收到请求并同意创建新连接”;序号为seq=y;确认号为ack=x+1,表示将来自客户端的报文序号seq值加1作为自己确认号ack的值;随后服务端进入SYN-RCVD状态
③客户端收到服务端的同意连接TCP报文后,确认了双方间数据传输是正常的,结束SYN-SENT状态,并返回最后一段TCP报文:
标志位为ACK=1,表示“已收到同意连接的信号”;序号为seq=x+1,表示将来自服务端的确认号ack值作为自己的序号值;确认号为ack=y+1,表示将来自服务端序号seq值加1作为自己的确认号ack的值;随后客户端进入ESTABLISHED状态
服务端收到来自客户端的确认连接TCP报文之后,也确认了双方间数据传输正常,结束SYN-RCVD状态,进入ESTABLISHED状态
在第三次握手时就可以携带数据了,因为能够发出第三次握手报文的客户端,肯定接收到来自服务端的第二次握手报文,而伪造IP的客户端是不会接收到第二次报文的,所以,能够发出第三次握手报文的就是合法的用户,服务端在接收到第三次握手的瞬间,状态就会切换为ESTABLISHED,里面携带的数据就可以按照正常流程走了
为何两次握手不可以呢?原因是为了防止服务端开启一些无用的连接增加服务器开销以及防止已失效的连接请求报文段突然又传送到了服务端而产生错误。“第三次握手”是客户端向服务端发送数据,目的是告诉服务器,客户端有没有收到服务器“第二次握手”时传过去的数据,若发送的是“收到了”的信号,服务端接收后就正常建立TCP连接,否则建立TCP连接失败,服务器关闭连接端口,由此减少服务器开销及防止接收到失效请求而导致错误
为什么是三次握手?首先要明确下TCP握手的目的是为了通信,能够完成数据传输。那么通信的前提就是客户端和服务端都要具备读写能力。
服务端收到客户端发来的请求(即第一次握手)能够证明客户端具备写的能力,接下来服务端给客户端进行回复信息(即第二次握手),客户端收到服务端回复的信息能够证明服务端具备读写的能力;客户端发送给服务端最后一段报文(即第三次握手),服务端收到后能够证明客户端具备读的能力。
1.5 TCP四次挥手
所谓四次挥手就是TCP连接断开的过程,下图为客户端主动发起断开连接的图解:
挥手之前主动释放连接的客户端结束ESTABLISHED状态,随后开始“四次挥手”:
①客户端向服务端发送TCP报文:
标志位为FIN=1,表示“请求释放连接”,序列号为seq=u,随后客户端进入FIN-WAIT-1状态并停止向服务端发送数据
②服务端收到从客户端发出的释放连接的TCP报文后结束ESTABLISHED状态,进入CLOSE-WAIT状态并返回一段TCP报文:
标志位为ACK=1,表示“收到释放请求”,序列号为seq=v,确认号ack=u+1,表示将来自客户端报文序号seq值加1作为自己的确认号ack的值,随后服务端进入CLOSE-WAIT状态
③客户端收到服务端确认结果后,进入FIN-WAIT-2状态。服务端做好了释放连接准备后再次向客户端发出一段TCP报文:
标志位为FIN=1,ACK=1,表示“已准备好释放”,序号为seq=w,确认号ack=u+1,服务器进入LAST-ACK状态并停止向客户端发送数据
④客户端收到回复后,结束FIN-WAIT-2状态,进入TIME-WAIT状态,并向服务端发送一段报文:
标志位为ACK=1,表示“已收到准备释放信号”,序列号为seq=u+1,确认号为ack=w+1,表示将来自服务端报文序号seq值加1作为自己的确认号ack的值,客户端进入TIME-WAIT状态,客户端经过2MSL后进入CLOSE状态;服务器收到确认后,立刻进入CLOSE状态
MSL指的是Maximum Segment Lifetime:一段TCP报文在传输过程中的最大生命周期。2MSL即是服务端发出为FIN报文和客户端发出的ACK确认报文所能保持有效的最大时长。
为什么是四次挥手?客户端要断开连接,会给服务端发送一段FIN报文(第一次挥手),此时服务端会立刻响应回复给客户端一段报文(第二次挥手),表示服务端收到了客户端的断开请求,不会再有数据发送过来了,但这时客户端仍然可以收到服务端发过来的数据。因为服务端的数据可能还没有发送完毕。等到服务端数据全部发送完成后,才会发送自己的一段FIN报文给客户端(第三次挥手),表示服务端也准备断开连接了,不会再有数据发送。客户端收到服务端的断开请求,会响应一段报文给服务端(第四次挥手),最后双方都断开了连接。