TCP

作者: junden | 来源:发表于2016-08-24 18:05 被阅读0次

    tcp报文段首部

    • 最前面两个分别是源端口和目的端口,各占2个字节
    • Sequence Number是包的序号,用来解决网络包乱序(reordering)问题(seq是初始化序号的简称)。
      • 比如:一段报文,seq为301,携带100字节的数据,表明第一个字节的序号是301,最后的字节序号是400,期望下一个报文段的数据序号从401开始,则服务器或客户端发的下一个报文段的序号字段应为401.
    • Acknowledgement Number就是ACK——用于确认收到,用来解决不丢包的问题。(此为确认号,并非tcp flag的ACK)
      • 期望收到对方下一个报文段的第一个数据字节序号。如若ACKnum = N,则表明到N-1为止的所有数据都已经正确收到。
    • TCP Flag ,也就是包的类型,主要是用于操控TCP的状态机的。
      • URG:当TCP Flag中的URG为1时,则表明紧急指针字段有效,告诉操作系统,报文段中有紧急数据、
      • ACK:仅当ACK =1时,确认号才有效。当ACK = 0时,确认号是无效的。TCP规定,在连接建立后所有传送的报文段都必须把ACK设为1。(有效的确认连接已经建立)
      • PUSH(推送):当这个设置为1时,接收方会尽快的将收到的报文段交付给接受应用进程,而不等到缓存满了再交付
      • RST(复位):当收到的报文段rst为1时,表明tcp连接中出现严重的差错,必须释放连接,然后再重新建立连接,还用来拒绝一个非法报文段和拒绝打开一个连接。
      • SYN(同步):在连接建立时用来同步序号。当SYN =1而ACK =0时,表明这是一个请求连接报文段。对方若同意建立连接,则应当在响应报文段中使用SYN=1 和ACK =1。
      • FIN(终止): 用来释放一个连接,当FIN = 1 时,表明此报文段的发送方的数据已经发送完毕,并要求释放连接。
    • Window又叫Advertised-Window,也就是著名的滑动窗口(Sliding Window),用于解决流控的
      • 窗口指的是发送本报文段的一方的接受窗口。窗口值告诉对方:本报文段首部的确认好算起,接收方目前允许对方发送的数据量。窗口值作为接收方让发送方设置其发送窗口的依据
      • 比如,确认号是701,窗口字段是1000,这就表明,从701�号算起,发送此报文段的一方还有接受1000个字节数据(字节序号是701~1700)的接受缓存空间。

    tcp三次握手

    • TCP是面向连接的协议,为什么要三次握手呢?
      • 要使每一方能够确知对方的存在
      • 避免了服务器资源的浪费,预防连接请求延迟到达时,服务器依旧打开连接等待客户端。
    • 默认情况下,client(客户端)为主动打开连接,server(服务端)为被动打开连接。
    • 1.一般服务器进程会先创建传输控制块TCB,准备接受客户端的连接请求,然后服务器进程就处于listen(监听)状态,等待连接请求。
    • 2.client进程在发起连接之前也会创建一个TCB,然后向server发出连接请求报文段,这时候首部的同步位SYN =1,同时会选择一个初始化序号seq = x。tcp规定,SYN报文段不能携带数据,但要消耗一个序号,这时候发送完SYN报文后,client进入SYN-SENT(同步已发送)状态.
    • 3.server收到请求报文段后(SYN报文),如同意建立连接,则向client发送确认报文段,在确认报文段首部把SYN位和ACK位都设置为1.,然后AckNum确认号 为x+1,同时也为自己选择一个初始化序号seq = y
      在此报文段中依然不能携带数据,但同样要消耗掉一个序号,此时server进入SYN-RCVD(同步收到)状态
    • 4.此时client收到server的确认后,还要给server发送确认,此时是第三次握手。发送的确认报文段ACK置1确认号AckNum为 ack= y+1.而自己的序号seq = x+1,这时候,tcp规定可以携带数据,但不携带数据则不消耗序号。这说明,下一个数据报文段的seq仍是 x+1.这时候。tcp连接已经建立,client也进入ESTABLISHED(已建立连接状态).
    • 5.当server收到client的确认后,也进入了ESTABLISHED状态
    • 三次握手主要是为了防止已失效的连接请求报文突然又传送到server,因而产生错误,从而浪费server的资源。有了第三次的话,client不发送第三次确认server的确认,server由于收不到第三次确认,就是的client并没有需要建立连接。

    四次握手,释放连接

    • 1.同理三次握手,client先发送一个连接释放报文段给server,并停止发送数据,主动关闭tcp连接,这个报文段的首部将tcp flag中的FIN为设置为1,然后将seq = u,等于把前面已传送过去的数据最后一个字节+1.此时client由ESTABLISHED状态进入FIN-WAIT-1(终止等待1)状态。等待server的确认,请注意,FIN报文段即使不携带数据,也会消耗一个序号。

    • 2.当server收到FIN报文后,会立即发出确认ack=1,ACKnum =u +1,然后自己的序号为v,发出去后则进入CLOSE-WAIT(关闭等待)状态.这个时候server会通知高层应用进程,这时TCP连接进入半关闭(half-close)状态,就是client已经没有数据发给server,而server如果还有数据发给client,client仍要接收,这个状态还持续一段时间。

    • 3.当client收到server的确认后,就进入了FIN-WAIT-2(终止等待2)状态,等待server发出关闭连接报文。

    • 4.当server已经没有更多数据要向client发送的时候,就会发出server的FIN报文段,然后必须重复发送上次的确认号AckNum为 ack= u+1,在设置自己的序号seq=w此时server就会进入LAST-ACK(最后确认)状态,等待client的确认。

    • 5.当client受到server的连接释放报文后,必须对此发出确认。在确认报文段把ack置1确认号AckNum为 ack= w+1。而自己的序号为 seq = u+1。然后则进入 TIME-WAIT。此时TCP连接还没释放,必须等待2MSL(2次最长报文段寿命:2*2分钟).等待完后才进入CLOSED状态,而server收到最后ACK的时候就会进入CLOSED,比client早一点。

    • 为什么需要等待2MSL时间呢?

      • 1.为了保证client发送的最后一个ACK报文段能够到达server,假如,这个最后ACK报文段丢失了,则server就处在LAST-ACK状态中,一直收不到自己刚刚发给client的FIN+ACK的报文段的确认报文。server就会再次重传一次FIN+ACK。而client就能在2MSL时间内收到重传的FIN+ACK报文,从而client在最后TIME-WAIT的状态中可以再次重传一次对server的FIN+ACK报文的确认报文。重启2MSL计时器。
      • 这样如果client不在TIME-WAIT等待一段时间,而是在发送第一次ACK报文后立即释放连接,如果这个ACK报文丢失后,就无法收到server重传的FIN+ACK报文,因而不会再次发送ACK报文段,server就无法正常进入CLOSED状态。
      • 2.还有一个原因是为了防止已经失效的报文段在新的连接中出现。因为client发送完最后一个ACK报文段后,等待2MSL后,会使本次连接内所有产生的报文段在网络中小时。

    总结

    • 无论三次握手与四次握手,双方的序号seq与acknum都要保持同步,比如server发送seq =x,client则会发送acknum=x+1.
    • 每次握手都需要确认上一次握手,tcp flag中的标志位是发起连接或者释放连接的关键。

    参考:http://coolshell.cn/articles/11564.html

    相关文章

      网友评论

          本文标题:TCP

          本文链接:https://www.haomeiwen.com/subject/rsjosttx.html