Transmission Control Protocol 传输控制协议算法
面向链接的、可靠的、基于字节流的传输层通讯协议缓存
应用层向TCP层发送用于网间传输的8位字节表示的数据流,TCP则把数据流分割成适当长度的报文段,最大传输段大小(MSS)一般受该计算机链接的网络的数据链路层的最大传送单元(MTU)限制。以后TCP把数据包传给IP层,由IP层来经过网络将包传送给接收端实体的TCP层。服务器
为了保证报文传输的可靠,给每一个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收;而后接收端实体对已成功收到的字节发回一个相应的确认(ACK);若是发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据将会被重传。网络
在接收端存在一个接收缓存区,用来接收来自于发送方的数据,只有当应用进程从接收缓存区中取出数据(可能只是部分)并发出其ACK后,才算做这部分数据已经接收,而后调节此时的滑动窗口大小。发送方根据返回的窗口大小,计算出所能发送的数据大小。所以,能够这么理解:滑动窗口算法是接收端做为主动方根据自身的缓存以及处理能力主动去调节对方的发送流量的一种调节算法。并发
Client端所经历的状态:函数
Server端所经历的状态:大数据
确保创建可靠的通讯信道。spa
客户端调用connect函数,触发了链接请求,向服务器发送了SYN J包,这时connect进入阻塞状态, 在三次握手的第二次返回;
服务器监听到链接请求,收到SYN J包,调用accept函数接收请求向客户端发送SYN K ,ACK J+1,这时accept进入阻塞状态, 在三次握手的第三次返回;
关于第三次握手的解释3d
第三次握手主要是为了防止已失效的请求报文段忽然又传送到了服务端而产生链接的误判
好比:客户端发送了一个链接请求报文段A到服务端,可是在某些网络节点上长时间滞留了,然后客户端又超时重发了一个链接请求报文段B该服务端,然后正常创建链接,数据传输完毕,并释放了链接。可是请求报文段A延迟了一段时间后,又到了服务端,这本是一个早已失效的报文段,可是服务端收到后会误觉得客户端又发出了一次链接请求,因而向客户端发出确认报文段,并赞成创建链接。假如没有三次握手,这时服务端只要发送了确认,新的链接就创建了,但因为客户端没有发出创建链接的请求,所以不会理会服务端的确认,也不会向服务端发送数据,而服务端却认为新的链接已经创建了,并在一直等待客户端发送数据,这样服务端就会一直等待下去,直到超出保活计数器的设定值,而将客户端断定为出了问题,才会关闭这个链接。这样就浪费了不少服务器的资源。而若是采用三次握手,客户端就不会向服务端发出确认,服务端因为收不到确认,就知道客户端没有要求创建链接,从而不创建该链接。指针
当收到对方的FIN报文通知时,仅仅表示对方没有数据发送过来了,但未必服务端全部的数据都所有发送给对方了,因此未必会立刻会关闭SOCKET, 可能还须要发送一些数据给对方以后,再发送FIN报文给对方来表示赞成如今能够关闭链接了,因此这里的ACK报文和FIN报文多数状况下都是分开发送的。
Q: 为何创建链接是三次握手,而关闭链接倒是四次挥手呢?
A: TCP全双工链接。 这是由于服务端在LISTEN状态下,收到创建链接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭链接时,当收到对方的FIN报文时,仅仅表示对方再也不发送数据了可是还能接收数据,己方也未必所有数据都发送给对方了,因此己方能够当即close,也能够发送一些数据给对方后,再发送FIN报文给对方来表示赞成如今关闭链接,所以,己方ACK和FIN通常都会分开发送。
Q: 为何TIMEWAIT状态还须要等2MSL后才能返回到CLOSED状态? S: 保证TCP协议的全双工链接可以可靠关闭,保证此次链接的重复数据段从网络中消失。 虽然双方都赞成关闭链接了,并且握手的4个报文也都协调和发送完毕,按理能够直接回到CLOSED状态(就比如从SYN_SEND状态到ESTABLISH状态那样);可是假想网络是不可靠的,没法保证最后发送的ACK报文会必定被对方收到,所以对方处于LAST_ACK状态下的SOCKET可能会由于超时未收到ACK报文,而重发FIN报文,因此这个TIMEWAIT状态的做用就是用来重发可能丢失的ACK报文。