TCP

Transmission Control Protocol 传输控制协议算法

面向链接的、可靠的、基于字节流的传输层通讯协议缓存

带重传的ACK确认技术来实现传输的可靠性

应用层向TCP层发送用于网间传输的8位字节表示的数据流,TCP则把数据流分割成适当长度的报文段,最大传输段大小(MSS)一般受该计算机链接的网络的数据链路层的最大传送单元(MTU)限制。以后TCP把数据包传给IP层,由IP层来经过网络将包传送给接收端实体的TCP层。服务器

为了保证报文传输的可靠,给每一个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收;而后接收端实体对已成功收到的字节发回一个相应的确认(ACK);若是发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据将会被重传。网络

  1. 应用数据分割成TCP认为最适合发送的数据块,这部分是经过“MSS”(最大数据包长度)选项来控制的.
  2. 重传机制。设置定时器,等待确认包。
  3. 对首部和数据进行校验。
  4. TCP对收到的数据进行排序,而后交给应用层
  5. TCP的接收端丢弃重复的数据。
  6. TCP还提供流量控制。

流量控制机制——滑动窗口

在接收端存在一个接收缓存区,用来接收来自于发送方的数据,只有当应用进程从接收缓存区中取出数据(可能只是部分)并发出其ACK后,才算做这部分数据已经接收,而后调节此时的滑动窗口大小。发送方根据返回的窗口大小,计算出所能发送的数据大小。所以,能够这么理解:滑动窗口算法是接收端做为主动方根据自身的缓存以及处理能力主动去调节对方的发送流量的一种调节算法并发

首部格式

  

  • Source Port : 源端口,16位。
  • Destination Port:   目的端口,  16位。
  • Sequence Number:   Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
  • Acknowledgment Number:   ack确认序号,占32位。只有ACK标志位为1时,确认序号字段才有效,ack=Seq+1。
  • Data Offset:   数据偏移, 4位,该字段的值是TCP首部(包括选项)长度除以4。
  • Window: 接收缓冲区的空闲空间,16位,用来告诉TCP链接对端本身可以接收的最大数据长度。
  • Checksum:校验和,16位。
  • Urgent Pointers是紧急指针,16位,只有URG标志位被设置时该字段才有意义,表示紧急数据相对序列号(Sequence Number字段的值)的偏移。
  • 标志位:共6个
    • URG:表示Urgent Pointer字段有意义。
    • ACK:表示Acknowledgment Number有效。
    • PSH:接收方应该尽快将这个报文交给应用层。
    • RST:重置链接。
    • SYN:发起一个新链接。
    • FIN:释放一个链接。

工做过程

Client端所经历的状态:函数

Server端所经历的状态:大数据

 

三次握手链接

确保创建可靠的通讯信道spa

image

  • Client向Server发送一个SYN=1, seq=J。 Client进入SYN_SENT状态,等待Server确认。
  • LISTEN)Server 校验SYN=1, 并向Client响应 SYN=1, ACK=1, ack=J+1, seq=K 。 Server进入SYN_RCVD状态 (半链接状态)。
  • Client 校验ACK=1, ack=J+1; 返回:SYN=0, ACK=1, ack=K+1。
  • Server检查ack =K+1,ACK = 1; 正确则链接,Client和Server进入ESTABLISHED状态。

客户端调用connect函数,触发了链接请求,向服务器发送了SYN J包,这时connect进入阻塞状态, 在三次握手的第二次返回;
服务器监听到链接请求,收到SYN J包,调用accept函数接收请求向客户端发送SYN  K ,ACK J+1,这时accept进入阻塞状态, 在三次握手的第三次返回;

关于第三次握手的解释3d

第三次握手主要是为了防止已失效的请求报文段忽然又传送到了服务端而产生链接的误判 
好比:客户端发送了一个链接请求报文段A到服务端,可是在某些网络节点上长时间滞留了,然后客户端又超时重发了一个链接请求报文段B该服务端,然后正常创建链接,数据传输完毕,并释放了链接。可是请求报文段A延迟了一段时间后,又到了服务端,这本是一个早已失效的报文段,可是服务端收到后会误觉得客户端又发出了一次链接请求,因而向客户端发出确认报文段,并赞成创建链接。假如没有三次握手,这时服务端只要发送了确认,新的链接就创建了,但因为客户端没有发出创建链接的请求,所以不会理会服务端的确认,也不会向服务端发送数据,而服务端却认为新的链接已经创建了,并在一直等待客户端发送数据,这样服务端就会一直等待下去,直到超出保活计数器的设定值,而将客户端断定为出了问题,才会关闭这个链接。这样就浪费了不少服务器的资源。而若是采用三次握手,客户端就不会向服务端发出确认,服务端因为收不到确认,就知道客户端没有要求创建链接,从而不创建该链接。指针

四次握手释放

image

当收到对方的FIN报文通知时,仅仅表示对方没有数据发送过来了,但未必服务端全部的数据都所有发送给对方了,因此未必会立刻会关闭SOCKET, 可能还须要发送一些数据给对方以后,再发送FIN报文给对方来表示赞成如今能够关闭链接了,因此这里的ACK报文和FIN报文多数状况下都是分开发送的。

  1. Client------>FIN, seq=M ------>Server; Client进入FIN_WAIT_1状态 (告知服务端再也不发送数据了请求关闭通讯);
  2. Server------>校验FIN;返回ACK=1, ack=M+1------>Client,Server进入CLOSE_WAIT状态。(知道了客户端关闭请求,可是要等服务端把数据所有返回)
  3. Server------>FIN, seq=N-----Client; Server进入LAST_ACK状态。Client进入FIN_WAIT_2状态。半关闭链接
  4. Client--->FIN, ACK=1, ack=N+1 ------>Server; Client进入TIME_WAIT状态,Server进入CLOSED状态,完成四次挥手。Client等2MSL (Maximum Segment Lifetime,报文最大生存时间)后便可回到CLOSED可用状态

FAQ

  1. Q: 为何创建链接是三次握手,而关闭链接倒是四次挥手呢?
    A: TCP全双工链接。 这是由于服务端在LISTEN状态下,收到创建链接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭链接时,当收到对方的FIN报文时,仅仅表示对方再也不发送数据了可是还能接收数据,己方也未必所有数据都发送给对方了,因此己方能够当即close,也能够发送一些数据给对方后,再发送FIN报文给对方来表示赞成如今关闭链接,所以,己方ACK和FIN通常都会分开发送。

  2. Q: 为何TIMEWAIT状态还须要等2MSL后才能返回到CLOSED状态? S: 保证TCP协议的全双工链接可以可靠关闭,保证此次链接的重复数据段从网络中消失。 虽然双方都赞成关闭链接了,并且握手的4个报文也都协调和发送完毕,按理能够直接回到CLOSED状态(就比如从SYN_SEND状态到ESTABLISH状态那样);可是假想网络是不可靠的,没法保证最后发送的ACK报文会必定被对方收到,所以对方处于LAST_ACK状态下的SOCKET可能会由于超时未收到ACK报文,而重发FIN报文,因此这个TIMEWAIT状态的做用就是用来重发可能丢失的ACK报文。

相关文章
相关标签/搜索