zoukankan      html  css  js  c++  java
  • 你应该这么理解TCP的三次握手和四次挥手

    前言:


    1. TCP协议是计算机的基础,他本身是一个非常非常复杂的协议。
    2. 本文只是蜻蜓点水,将从网络基础以及TCP的相关概念介绍开始,之后再将三次握手,四次挥手这些内容来阐述。
    3. 最后介绍一些常见问题,并给出解答。

     网络分层


    在实际的网络中,我们是四层网络结构:

    网络传输层

    网络传输层负责最底层的底层链路连接。两台主机之间进行互联,基于网线的物理硬件上的协议。在这个侧面,主机与主机之间只认得硬件mac编码。并不认识IP。

    网络层

    IP就是在网络层出现的,就像网络上,每个机器的地址。网络层可以理解为快递,它的职能就是根据地址(IP),把东西从一个地方运送到另一个地方

    传输层

    传输层相比于网络层最大的不同就是引入了端口的概念。网络层只管发送地址和目的地址。但是发送主机上有可能有多个程序和同一个接收主机进行传输数据,怎么区分这多个程序呢?就引入了端口的概念。(发送IP地址,发送端口,接收IP地址,接收端口)四元组标示了一个主机的程序到另一个主机程序的唯一标示。传输层的职能,就是维护这个四元组。

    其实传输层还有一个职能是定义发送方和接收方基本处理包的行为。上面说到网络层就相当于邮件运输工,它只负责把一包东西从一个地方放到另外一个地方,但是,这包东西是否送达了,送达之后接收方又有什么行为。这些都可以在传输层进行定义。注意,这里说的是可以,你也可以在传输层布不管这些,只做简单的基本封装四元组,比如UDP

    应用层

    指定到主机端口了,接下来就是应用层干活了,可以传文件,传文本。应用层就是实际上对具体的程序之间的交互功能进行定义的层。

    TCP协议


    TCP(Transmission Control Protocol) 传输控制协议.TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接。

    协议结构如下:

    这里就不全部都讲了,主介绍一部分:

    Source Port和Destination Port

    这两个字段表示发送地址和目的地址的端口号,发送地址的IP和目的地址的IP是在IP协议头中

    Sequence number(顺序号码) Acknowledge number(确认号码)

    TCP的任意一端(不管是客户端还是服务端),可以发送数据,也可以接受数据。那么发送序列号就是Seqence Number,接受序列号就是Acknowledgement Number。

    其次,序列号是用来标志包的顺序的。网络中包由于网络问题,接受到的并不是按顺序到达的,接受端可以根据这个序列号来进行组装。

    比如:

    给服务端发送8000字节的数据,顺序号从10000开始,分成4个包发送,那么它们的标识就是12000,14000,16000,18000。

    如下图所示,由于网络问题,最先到达的是序号为14000,但是服务端可以根据这些包的序号进行拼接,拼成完整的包。

     

    Data offset和Reserved

    由于tcp头可能是不固定大小的(因为存在可选字段),所以需要有这个值来表示当前这个包的tcp头有多大。

    Reserved就是保留字段

    位码TCP标志位

    就是下图中的红框的内容

    SYN(synchronous建立联机):建立连接,发送一方告知另外一方,请求建立连接

    ACK(acknowledgement 确认):该包中有回复信息

    PSH(push传送):该包中有传输信息

    FIN(finish结束):结束位,发送一方告知另外一方,请求中断连接

    RST(reset重置):重置位,这个包是用来要对方重置连接

    URG(urgent紧急):紧急位,已经建议弃用

     

    握手与挥手:


     有了上面的基础知识,相信下面的三次挥手和四次握手理解起来也不会费劲的。

    下图是三次握手的过程:

    三次握手过程说明:

    TCP服务器进程先创建传输控制块TCB(存储了每一个连接中的一些重要信息,如:TCP连接表,到发送和接收缓存的指针,到重传队列的指针,当前的发送和接收序号,等),准备接受客户进程的连接请求。然后服务器进程就处于LISTEN(收听)状态,等待客户的连接请求。如有,即作出相应。

    第一次握手:

    客户端Client向服务端Server发起建立连接请求。客户端会发送位码SYN(请求建立连接),以及序列号x(seq=x),TCP规定,SYN报文段(即SYN=1的报文段)不能携带数据,但要消耗掉一个序号。这时,TCP客户进程进入SYN-SENT(同步已发送)状态。

    第二次握手:

    服务端Server接受到请求报文段之后。如同意建立连接,则向客户端发送确认消息。在确认报文段中应把SYN位和ACK位都置1,确认号是ack=x+1,同时也为自己选择一个初始序号seq=y。注意。这个报文段也不能携带数据,但同样要消耗掉一个序号。这时服务端进程进入SYN-RCVD(同步收到)状态。

    第三次握手:

    客户端Client收到服务端Server的确认后,还要向服务端给出确认。确认报文段的ACK置1,确认号ack=y+1,而自己的序号seq=x+1。这时,TCP连接已经建立,客户端进入ESTABLISHED(已连接状态)。当服务端收到客户端的确认之后,也进入ESTABLISHED状态。

    总结:

    客户端在三次握手中,状态的转变是:CLOSED->SYN_SEND->ESTABLISHED

    服务端在三次握手中,状态的转变是:CLOSED->LISTENED->SYN_RCVD->ESTABLISHED

    问题一:为什么不可以两次握手,为什么客户端还要再发送一次确认?

    答:消除旧有连接请求的SYN消息对新连接的干扰,同步连接双方的序列号和确认号并交换TCP 窗口大小信息。

      比如说这种异常情况:客户端发出的第一个连接请求报文段并没有丢失,而是在某些网络结点长时间滞留了,以致延误到连接释放以后的某个时间才到达服务端。本来这是一个早已失效的报文段。但服务端收到此失效的连接请求报文段后,就误以为是客户端又发出一次新的连接请求。于是就向客户端发出确认报文段,同意建立连接。假定不采用三次握手,那么只要服务端发出确认,新的连接就建立了。

    问题二:什么是SYN攻击?如何检测它?

       在三次握手过程中,服务器发送SYN-ACK之后,收到客户端的ACK之前的TCP连接称为半连接(half-open connect).此时服务器处于Syn_RECV状态.当收到ACK后,服务器转入ESTABLISHED状态.

      Syn攻击就是 攻击客户端 在短时间内伪造大量不存在的IP地址,向服务器不断地发送syn包,服务器回复确认包,并等待客户的确认,由于源地址是不存在的,服务器需要不断的重发直 至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。

      Syn攻击是一个典型的DDOS攻击。检测SYN攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击.在Linux下可以如下命令检测是否被Syn攻击:

    netstat -n -p TCP | grep SYN_RECV

    一般较新的TCP/IP协议栈都对这一过程进行修正来防范Syn攻击,修改tcp协议实现。主要方法有SynAttackProtect保护机制、SYN cookies技术、增加最大半连接和缩短超时时间等.

    但是不能完全防范syn攻击。

    四次挥手过程说明:

     在客户端和服务端已经建立连接的情况下,需要四次挥手来断开连接。如下图所示:

    第一次挥手:

    客户端发送一个FIN=1的报文段和顺序号为u(seq=u)的请求关闭消息(客户端没有消息要发给你了,我准备关闭连接了,但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK)。客户端进入FIN-WAIT-1状态,等待服务端的FIN报文段。

    第二次挥手:

    服务端收到客户端的FIN报文段,会发送一个确认报文段ACK=1,以及确认序列号ack=u+1,还有自己的序列号seq=v(告诉客户端,我已经收到你的请求关闭消息,但是我还没准备好,请继续等待),服务单进入CLOSE-WAIT阶段,此时服务端还未关闭。

    第三次挥手:

    服务端向客户端发送FIN=1报文段(告诉Client端,好了,我这边数据发完了,准备好关闭连接了),ACK=1,序列号seq=w,ack=u+1,服务端进入LAST-ACK状态

    第四次挥手:

    客户端收到服务端发来的FIN=1报文段,给服务端发送ACK=1报文段,序列号seq=u+1,ack=w+1的消息。这时客户端就可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传 ,客户端等待了2MSL后依然没有收到回复,客户端关闭。服务端也关闭。

    总结:

    客户端在四次挥手中的状态变化是:ESTABLISHED -> FIN-WAITED-1 -> FIN-WAITED-2 -> TIME-WAITED -> CLOSED

    服务单在四次挥手中的状态变化是:ESTABLISHED -> CLOSE-WAITED LAST-ACK -> CLOSED

     

    问题一:为什么在第四次回收后会有2个MSL的延时?

    首先了解MSL,Maximum Segment Lifetime,最大报文生存时间,2个MSL是报文段发送和接受的最长时间。

    假定网络不可靠,那么第四次发送的ACK可能丢失,即服务端无法收到这个ACK,如果服务端收不到这个确认ACK,服务端会定时向客户端端重复发送FIN,直到服务单端收到客户端的确认ACK。所以这个2MSL就是用来处理这个可能丢失的ACK的。

    问题二:为什么握手只要三次,挥手却需要四次?

    在TCP连接中,服务端SYN和ACK向客户端发送是一次性发送的,而在断开连接的过程中,服务端向客户端发送的ACK和FIN是分两次发送的。因为在服务端接受到客户端的FIN后,服务端还有数据要传输的话,所以先发送ACK,等服务端处理完自己的事情后就可以发送FIN断开连接了。

    下篇预告:

    TCP长连接与短连接,与Socket的联系

    参考链接:

    漫谈TCP

    TCP的三次握手和四次挥手

    TCP协议三次握手过程分析

    计算机网络——TCP三次、四次握手详解

  • 相关阅读:
    PAT A1094 The Largest Generation (25 分)——树的bfs遍历
    PAT A1055 The World's Richest (25 分)——排序
    PAT A1052 Linked List Sorting (25 分)——链表,排序
    PAT A1076 Forwards on Weibo (30 分)——图的bfs
    辅导员
    辅导员面试
    C程序设计
    Excel VBA 基本概念
    Excel函数
    导入excel表的数据到数据库ssh
  • 原文地址:https://www.cnblogs.com/superfj/p/9138452.html
Copyright © 2011-2022 走看看