关于TCP协议的博客一直没有开始写,是因为一直不确定自己对TCP协议的认识是否正确,在近些时间查阅了很多书籍,文章之后,感觉对TCP协议有了一个大致的认识,因此开始写此篇博客.(大多数人在学习TCP协议时,都习惯与UDP协议对比着学习,实际上这样学习TCP也是完全可以的,因为很多TCP协议的特性与UDP协议的特性是完全对立的,所以如果要进行对比学习TCP协议的话,可以用此篇博客结合之后的UDP协议的博客进行对比学习)
TCP协议作为TCP/IP协议的核心协议,一直都是面试的必考题,也是对网络知识学习的检票员,所以对TCP协议有一个全面且清晰且正确的认识,是一个非常有必要的事情.
什么是TCP协议
TCP协议全称为传输控制协议,是TCP/IP协议的核心协议之一,位于TCP/IP协议4层模型的传输层.
传输层的作用
在发送数据时,传输层主要用于接收应用层的数据,对从应用层接受的数据进行封装处理,然后向下发送给网络层;
在接收数据时,传输层接收从网络层发来的数据,对数据进行再传输层的解析,将解析完毕的数据发送给应用层.
TCP协议的特性
- 有连接:在使用TCP协议进行数据传输时,首先要进行连接,确认连接无误后才可发送数据,在发送完数据之后,同样要进行断开连接.(通常将连接过程称为三次握手,断开过程称为四次挥手)
该图摘自
在TCP传输数据时,一般可将传输的两方设备分为客户端(client)和服务端(server).
三次握手: 建立连接之前服务端首先要处于监听(LISTEN)状态,发起连接由客户端首先发送一个SYN请求建立连接的数据包,客户端进入SYN_SENT状态等待应答,服务端在收到客户端发来的SYN请求连接的数据时,会回复给客户端一个ACK应答包,在这个ACK应答包中同样包含着客户端一个请求建立连接的数据,同时服务端进入SYN_RCVD状态,在收到服务端的应答数据(ACK) + 请求数据(SYN)时, 客户端回应服务端的请求信息,向服务端发送应答数据(ACK),同时客户端进入已连接状态,在服务端接收到应答数据(ACK)时,也立即进入连接状态,此时就可以互相传输数据,因为在连接时进过3次数据传输,因此连接过程被称为三次握手.
四次挥手: 在数据发送完毕后,需要进行断开连接,但在断开连接时,客户端和服务端都可以主动发起,所以这里可以将断开连接时的两端称为主动发起方和被动接受方,在断开连接时,主动发起方向被动接受方发送一个FIN数据包,并且进入FIN_WAIT_1状态,表示数据已传输完毕,请求断开连接,被动接受方在收到数据后先向主动发起方发送一个应答(ACK)包并进入等待关闭CLOSE_WAIT状态,在主动发起方接收到这个应答包后,立即进入FIN_WAIT_2状态,等待被动方发起断开请求,当被动接受方确认数据发送完毕后,会再次向主动发起方发送一个FIN+ACK(依然算是上一个应答包),请求关闭连接,并进入LAST_ACK状态,等待最后的应答包,在主动方收到被动方发送的请求关闭连接数据时,会向被动方发送一个应答包,表示可以进行断开了,随后主动方进入TIME_WAIT状态,在经过2MSL时长后关闭连接,释放资源,被动方在收到应答包后立即断开连接,释放资源,因断开连接时要经过四次数据传输过程,所以称之为四次挥手.
-
可靠传输:在TCP数据传输过程中TCP协议具有很多安全检测功能,保证数据传输过程中的可靠性.
数据传输前的连接过程就是一种可靠传输的保证.
在TCP进行数据传输时,会附加发送一个校验和,来保证数据的完整性.
TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层.
在TCP传输数据时还有一个可变大小的滑动窗口进行流量控制,防止缓冲区溢出.
还有一些机制进行网络拥塞控制.
最后还有超时重传(如果不能在有限时间内收到发送出数据的应答数据,会进行重新发送),确认应答(在收到数据后,要进行对数据接收到的应答数据的发送)等机制保证TCP传输数据的可靠性.
以上所有功能都为TCP的可靠特性提供了依据.
-
基于字节流
TCP 协议的数据并不会以消息为单位向目的主机传输,这些数据在某些情况下会被组合成一个数据段发送给目标的主机 ,其中不存在消息和数据包的概念,TCP在接收到上层数据后,会将数据放入一个缓冲区,然后从缓冲区读取数据进行发送,所以,使用TCP协议发送数据时,并不关心要发送的来自哪个数据包.
TCP协议常考问题
-
为什么是3次握手?
因为TCP协议是全双工通信协议,也就是说,TCP在进行数据传输时,两端都可以同时进行发送和接受数据,所以,在进行连接时,两端都要进行对环路的检测,首先客户端发起连接请求,在接收到应答后,客户端才可以确定环路通畅,可以进行数据 发送,服务端同样要进行检测,所以,服务端也要进行请求,并接收应答,在第二次握手时,将服务端的应答和请求压缩为一个数据包,所以需要进行3次握手,而2次不足以完成连接,4次则又多余,浪费资源.
-
为什么是4次挥手?
4次挥手是因为主动发起方首先要进行发起关闭请求,被动方收到后,要立即回复一个应答包,之后检测被动端数据是否发送完毕(发送完毕并且受到接收应答),在确认发送完毕后才会发起一个确认关闭请求,等待最后一个应答包,当主动方受到被动方发送的确认关闭请求时,会发送一个应答包,并进入TIME_WAIT状态,经过2MSL之后断开连接,被动方受到应答包之后直接进入关闭状态并释放资源.为什么关闭时应答包和请求关闭包不能合并,因为关闭时,主动方并不知道被动方数据是否已经发送完毕,被动方要检测所有数据发送完毕后才进行关闭请求.
-
为什么要进入TIME_WAIT状态等待2MSL?
MSL为一个数据包在网络中存活的最长时间,在最后一次应答包发送时,若在网络中丢失,就会导致被动方收不到应答包,一直处于等待状态,超时之后会请求主动方重新发送,若主动方此时已经关闭连接,则收不到此处的请求,就会导致被动方无法关闭.另外,如果不进行等待,若此时再重启一个客户端进行连接(假设使用端口一样),则可能导致上次在网络中残留的数据被此次连接接收到,导致数据混乱.
-
TCP协议握手时是否可以携带数据,可以在第几次握手时携带?
可以携带数据,可以在第三次携带,因为第三次握手时,若到达服务端,则表示连接无误,数据也自然可以到达服务端,若是未到达服务端,则表示连接失败,则不可以发送数据.第一次和第二次握手都不可以携带数据,因为第一次和第二次握手成功之后都不可以保证连接无误,若此时携带数据,则会破坏TCP协议的连接特性.
TCP协议虽然有很多优点,但是也有一个最致命的缺点,那就是传输速度慢,在进行了大量的可靠传输保证中消耗了很多性能,所以传输速率非常慢,在以后与UDP的对比中会越发明显