精华内容
下载资源
问答
  • TCP报文讲解

    千次阅读 2018-03-18 00:26:31
    TCP报文段分为首部和数据两部分,而首部字段的作用显示出了TCP报文的特性。理解好TCP报文的相关知识,对于理解TCP连接的三次握手有帮助,同时对Socket编程的学习也会有促进作用。TCP报文TCP报文段首部前20个字节是...

    在四层网络结构中,TCP和UDP是属于传输层,IP是网络层。TCP虽然是面向字节流的,但是TCP传送的数据单元却是报文段。TCP报文段分为首部和数据两部分,而首部字段的作用显示出了TCP报文的特性。理解好TCP报文的相关知识,对于理解TCP连接的三次握手有帮助,同时对Socket编程的学习也会有促进作用。

     

    TCP报文:

    TCP报文段首部前20个字节是固定的,可能后面有4n个字节是根据需要增加的,所以TCP首部有20+4n个字节,最少20个字节。

    TCP报文首部分别为:1.源端口  2.目的端口  3.序号Seq  4.确认号Ack  5.数据偏移  6.保留  7.紧急URG  8.确认ACK  9.推送PSH  10.复位RST  11.同步SYN  12.终止FIN  13.窗口  14.紧急指针  15.选项(长度可变)16.填充部分

     

    TCP报文如下图:

    TCP首部         TCP报文段的数据部分        
    IP报文分为IP首部和IP数据报的数据部分,其中IP数据报的数据部分包裹着TCP报文,一种层层封装的结构。
     

     

    TCP首部如下图所示:

    源端口    目的端口
    序号Seq
    确认号Ack
                                   数据偏移                                                                 保留                                紧急URG 确认ACK 推送PSH 复位RST 同步SYN 终止FIN                                                                                                                                                         窗口                                                                                                                   
      检验和  紧急指针
    选项(长度可变) 填充
    TCP报文首部到第五行,即选项字段之前的字节是固定的,共20个字节,后面4n个字节根据需要增加。
     
    1.源端口和2.目的端口:各占两个字节,TCP分用功能也是通过端口实现的。
     

    3.序号Seq:占4字节,共有2^32个序号,下一个又回到0。首部中这个序号字段Seq指的是本报文段所发送的数据的第一个字节的序号,比如某一报文段的字段值301,而携带的数据共有100个字节,则表明报文段的数据的第一个字节序号为301,最后一个字节的序号为400,因为TCP是面向字节流的。

    4.确认号Ack:占4个字节,表示期望收到对方下一个报文段的第一个数据字段的序号。如果说序号Seq是发送所携带数据的第一个字节的序号,那么确认号Ask是即将接收到的报文的数据的第一个字节的序号。

    5.数据偏移:占4位,表示TCP报文段的数据起始处距TCP报文段的起始处有多远,即TCP首部长度,即20+4n个字节。由于占4位,可以表示到2^4为16,能够表示的最大十进制数字是15,因此数据偏移的最大值为60字节,也就是说TCP报文首部最小为20字节,最大为60字节,也就说n最大为10。

    6.保留:占6位,保留为今后使用,目前置为0。

    7.紧急URG:当URG=1时,表明紧急指针字段有效,他告诉系统此报文段中有高优先级的数据,应优先传送。

    8.确认ACK:当ACK=1时确认号Ack才有效,ACK=0时,确认号无效。TCP规定,在建立连接后所有传送的报文段都必须把ACK置1。

    9.推送PSH:两个应用进程进行交互式通信,有时在一段的应用进程希望在键入一个命令后立即能够收到对方的响应,可以用到TCP的推送操作。PSH=1表示立即创建一个报文段并发送出去,当接收方TCP收到PSH=1的报文段时,就会尽快的交付给应用进程。

    10.复位RST:当RST=1时,表明TCP连接中出现严重错误,比如主机崩溃等,必须释放连接,然后再重连。RST=1还可用来拒绝一个非法的报文段,或拒绝打开一个连接。

    11.同步SYN:在连接建立时用来同步序号的,当SYN=1时且ACK=0时,表示这是一个连接请求,若对方同意连接,则应在响应的报文段中使SYN=1和ACK=1,因此SYN=1表示这是一个连接请求或者连接接受报文。

    12.终止FIN:作用用来释放一个连接,当FIN=1时,表明此报文段发送方的数据已经发送完毕,并要求释放运输连接。

    13,.窗口:占2个字节,表示发送报文段的那一方的一个接收窗口所能允许接受到对方发送的数据量的大小,比如说确认号Ack为701,窗口为1000,则表示下一次接收,从701序号开始,发送报文段的一方还有接收1000个字节数据。窗口值经常动态变化着。

    14.检验和:占2个字节,检验的范围包括首部和数据部分。

    15.紧急指针:占2字节。紧急指针仅指在URG=1时才有意义,它指出本报文段中紧急数据的字节数。当所有紧急数据都处理完毕,TCP就告诉应用程序恢复到正常操作。值得注意的是,即使窗口为0也可以发送紧急数据。

    16.选项:长度可变,最长可达40字节,也可以没有,即0字节。

     

    TCP的三次握手简述:

    SYN是同步控制字段,ACK是确认控制字段。Seq是序号,Ack是确认号

    第一次握手:client→Server,SYN=1且Seq=J

    第二次握手:server→client,SYN=1,ACK=1且Seq=K,Ack=J+1

    第三次握手:client→server,SYN=1,ACK=1且ACK=K+1

     

    TCP的三次握手:

    第一次握手:client端SYN=1,随机产生一个值Seq=J,数据报发送给server端,client端进入SYN_SENT状态,等待server确认。

    第二次握手:server端接收到数据报后通过SYN=1知道这是一个请求连接的数据报,于是server端的ACK和SYN都置为1,表示要发送一个连接接受的报文,并使确认号Ack生效,Ack=J+1,随机产生一个值Seq=K,于是将数据报发送给client端来确认连接请求。server端进入SYN_RCVD状态。

    第三次握手:client端收到确认之后,检查Ack是否为J+1和ACK是否为1,若是,则将ACK置为1,Ack=K+1,并将该数据包发送给server端,server端检查Ack是否等于K+1和ACK是否等于1,若是,则建立连接成功,client和sever都进入ESTABLISHED状态,之后client端和sever端就可以开始传递数据了。

     

    SYN攻击:

    三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接,也就是第二次握手之后和第三次握手之前的一段时间,此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将产时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。SYN攻击时一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了,使用如下命令可以让之现行:

    #netstat -nap | grep SYN_RECV

     

    四次握手:

    四次握手即终止TCP连接,指断开一个TCP连接时需要经过四次包的发送,在socket编程中一般都是通过close方法来触发的。TCP可以全双工通信,因此每个方向都要单独关闭。

    第一次握手:client发送一个FIN,表示关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态

    第二次握手:Server收到FIN后,发送一个Ack给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。表示答复第一次握手。

    第三次握手:Server发送一个FIN,表示关闭Server到Client的数据传送,Server进入LAST_ACK状态

    第四次握手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个Ack给Server,确认序号为收到序号+1Server进入CLOSED状态,完成四次挥手。

    <span style="color:#666666">上面是client方主动关闭,另一方被动关闭的情况,实际中还会出现同时发起主动关闭的情况。
    </span>

    可能有人会问,为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

    因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。

     

     

     

    展开全文
  • TCP 报文 tcp dup ack 、TCP Retransmission,快速重传,超时重传


    最近因使用FTP 上传数据的时候总是不能成功,抓包后发现 TCP 报文出现 TCP dup ackTCP Retransmission 两种类型的包。收集整理下
    TCP

    TCP dup ack (重复应答)

    [TCP dup ack XXX#X] 表示第几次重新请求某一个包,
    XXX表示第几个包(不是Seq),
    X表示第几次请求。
    丢包或者乱序的情况下,会出现该标志。
    图例中:第26548 第0 此请求 4468792 的包,重复 4申请了4次 ;

    [TCP Fast Retransmission] (快速重传)

    一般快速重传算法在收到三次冗余的Ack,即三次[TCP dup ack XXX#X]后,发送端进行快速重传。
    为什么是三次呢?因为两次 duplicated ACK 肯定是乱序造成的,丢包肯定会造成三次 duplicated ACK
    在这里插入图片描述
    在这里插入图片描述

    [TCP Retransmission] (超时重传)

    超时重传,如果一个包的丢了,又没有后续包可以在接收方触发[Dup Ack],或者**[Dup Ack]也丢失**的情况下,TCP会触发超时重传机制。
    超时重传

    [TCP Out-Of-Order] (报文乱序)

    [TCP Out-Of-Order]指的是TCP发送端传输过程中报文乱序了。

    [TCP Previous segment not captured]

    在TCP发送端传输过程中,该Seq前的报文缺失了。一般在网络拥塞的情况下,造成TCP报文乱序、丢包时,会出现该标志。
    需要注意的是,[TCP Previous segment not captured]解析文字是wireshark添加的标记并非TCP报文内容

    [TCP Out-Of-Order]

    TCP发送端传输过程中报文乱序了。

    Window

    [TCP ZeroWindow]

    作为接收方发出现的标志,表示接收缓冲区已经满了,此时发送方不能再发送数据,一般会做流控调整。接收窗口,也就是接收缓冲区win=xxx ,告诉对方接收窗口大小。

    传输过程中,接收方TCP窗口满了,win=0,wireshark会打上[TCP ZeroWindow]标签

    [TCP window update]

    接收方消耗缓冲数据后,更新TCP窗口, 可以看到从win=0逐渐变大,这时**wireshark会打上[TCP window update]**标签

    [TCP window Full]

    作为发送方的标识,当前发送包的大小已经超过了接收端窗口大小,wireshark会打上此标识,标识不能在发送。

    TCP慢启动

    慢启动是TCP的一个拥塞控制机制,慢启动算法的基本思想是当TCP开始在一个网络中传输数据或发现数据丢失并开始重发时,首先慢慢的对网路实际容量进行试探,避免由于发送了过量的数据而导致阻塞。
      慢启动为发送方的TCP增加了另一个窗口:拥塞窗口(congestion window),记为cwnd。当与另一个网络的主机建立TCP连接时,拥塞窗口被初始化为 1个报文段(即另一端通告的报文段大小)。每收到一个ACK,拥塞窗口就增加一个报文段(cwnd以字节为单位,但是慢启动以报文段大小为单位进行增加)。发送方取拥塞窗口与通告窗口中的最小值作为发送上限。拥塞窗口是发送方使用的流量控制,而通告窗口则是接收方使用的流量控制。发送方开始时发送一个报文段,然后等待 ACK。当收到该ACK时,拥塞窗口从1增加为2,即可以发送两个报文段。当收到这两个报文段的 A C K时,拥塞窗口就增加为4。这是一种指数增加的关系。

    拥塞避免算法

    拥塞避免

    网络中拥塞的发生会导致数据分组丢失,需要尽量避免。在实际中,拥塞算法与慢启动通常在一起实现,其基本过程:
       1. 对一个给定的连接,初始化cwnd为1个报文段,ssthresh为65535个字节。
       2. TCP输出例程的输出不能超过cwnd和接收方通告窗口的大小。拥塞避免是发送方使用 的流量控制,而通告窗口则是接收方进行的流量控制。前者是发送方感受到的网络拥塞的估 计,而后者则与接收方在该连接上的可用缓存大小有关。
       3. 当拥塞发生时(超时或收到重复确认),ssthresh被设置为当前窗口大小的一半(cwnd 和接收方通告窗口大小的最小值,但最少为2个报文段)。此外,如果是超时引起了拥塞,则 cwnd被设置为1个报文段(这就是慢启动)。
       4. 当新的数据被对方确认时,就增加cwnd,但增加的方法依赖于是否正在进行慢启动或拥塞避免。如果cwnd小于或等于ssthresh,则正 在进行慢启动,否则正在进行拥塞避免。慢启动一直持续到回到当拥塞发生时所处位置的半时候才停止(因为记录了在步骤2 中制造麻烦的窗口大小的一半),然后转为执行拥塞避免。
       慢启动算法初始设置cwnd为1个报文段,此后每收到一个确认就加 1。那样,这会使窗口按指数方式增长:发送 1个报文段,然后是2个,接着是4个……。

    TCP协议中的计时器

    TCP中有四种计时器(Timer),分别为:

    1. 重传计时器:Retransmission Timer
    2. 坚持计时器:Persistent Timer
    3. 保活计时器:Keeplive Timer
    4. 时间等待计时器:Timer_Wait Timer

    重传计时器

    大家都知道TCP是保证数据可靠传输的。怎么保证呢?带确认的重传机制。在滑动窗口协议中,接受窗口会在连续收到的包序列中的最后一个包向接收端发送一个ACK,当网络拥堵的时候,发送端的数据包和接收端的ACK包都有可能丢失。TCP为了保证数据可靠传输,就规定在重传的“时间片”到了以后,如果还没有收到对方的ACK,就重发此包,以避免陷入无限等待中。
      当TCP发送报文段时,就创建该特定报文的重传计时器。可能发生两种情况:
      1.若在计时器截止时间到之前收到了对此特定报文段的确认,则撤销此计时器。
      2.若在收到了对此特定报文段的确认之前计时器截止时间到,则重传此报文段,并将计时器复位。

    持久计时器

    先来考虑一下情景:
      发送端向接收端发送数据包知道接受窗口填满了,然后接受窗口告诉发送方接受窗口填满了停止发送数据。此时的状态称为“零窗口”状态,发送端和接收端窗口大小均为0.直到接受TCP发送确认并宣布一个非零的窗口大小。但这个确认会丢失。我们知道TCP中,对确认是不需要发送确认的。 若确认丢失了,接受TCP并不知道,而是会认为他已经完成了任务,并等待着发送TCP接着会发送更多的报文段。但发送TCP由于没有收到确认,就等待对方发送确认来通知窗口大小。双方的TCP都在永远的等待着对方。
      要打开这种死锁,TCP为每一个链接使用一个持久计时器。当发送TCP收到窗口大小为0的确认时,就坚持启动计时器。当坚持计时器期限到时,发送TCP就发送一个特殊的报文段,叫做探测报文。这个报文段只有一个字节的数据。他有一个序号,但他的序号永远不需要确认;甚至在计算机对其他部分的数据的确认时该序号也被忽略。探测报文段提醒接受TCP:确认已丢失,必须重传。
      坚持计时器的值设置为重传时间的数值。但是,若没有收到从接收端来的响应,则需发送另一个探测报文段,并将坚持计时器的值加倍和复位。发送端继续发送探测报文段,将坚持计时器设定的值加倍和复位,直到这个值增大到门限值(通常是60秒)为止。在这以后,发送端每个60秒就发送一个探测报文,直到窗口重新打开。

    保活计时器

    保活计时器使用在某些实现中,用来防止在两个TCP之间的连接出现长时间的空闲。假定客户打开了到服务器的连接,传送了一些数据,然后就保持静默了。也许这个客户出故障了。在这种情况下,这个连接将永远的处理打开状态。
      要解决这种问题,在大多数的实现中都是使服务器设置保活计时器。每当服务器收到客户的信息,就将计时器复位。
      通常设置为两小时。若服务器过了两小时还没有收到客户的信息,他就发送探测报文段。若发送了10个探测报文段(每一个相隔75秒)还没有响应,就假定客户除了故障,因而就终止了该连接。
      这种连接的断开当然不会使用四次握手,而是直接硬性的中断和客户端的TCP连接。

    时间等待计时器

    时间等待计时器是在四次握手(挥手)的时候使用的。四次握手的简单过程是这样的:假设客户端准备中断连接,首先向服务器端发送一个FIN的请求关闭包(FIN=final),然后由 established 过渡到FIN-WAIT1状态。服务器收到FIN包以后会发送一个ACK,然后自己有established进入CLOSE-WAIT.此时通信进入半双工状态,即留给服务器一个机会将剩余数据传递给客户端,传递完后服务器发送一个FIN+ACK的包,表示我已经发送完数据可以断开连接了,就这便进入LAST_ACK阶段。客户端收到以后,发送一个ACK表示收到并同意请求,接着由FIN-WAIT2进入TIME-WAIT阶段。服务器收到ACK,结束连接。此时(即客户端发送完ACK包之后),客户端还要等待2MSL(MSL=maxinum segment lifetime最长报文生存时间,2MSL就是两倍的MSL)才能真正的关闭连接。
      四次挥手
      附加:
      
    三次握手

    展开全文
  • TCP报文头部

    千次阅读 2019-08-18 16:27:42
    TCP报文固定长度20字节+可变长度 TCP包头如下图所示: 源端口、目标端口:计算机上的进程要和其他进程通信是要通过计算机端口的,而一个计算机端口某个时刻只能被一个进程占用,所以通过指定源端口和目标端口,...

    TCP包头详解

    主要学习端口号、三次握手、四次挥手

    TCP包头

    • TCP报文固定长度20字节+可变长度

    • TCP包头如下图所示:

    • 源端口、目标端口:计算机上的进程要和其他进程通信是要通过计算机端口的,而一个计算机端口某个时刻只能被一个进程占用,所以通过指定源端口和目标端口,就可以知道是哪两个进程需要通信。源端口、目标端口是用16位表示的,可推算计算机的端口个数为2^16个

    • 序列号:表示本报文段所发送数据的第一个字节的编号。在TCP连接中所传送的字节流的每一个字节都会按顺序编号。由于序列号由32位表示,所以每2^32个字节,就会出现序列号回绕,再次从 0 开始

    • 确认号:表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。也就是告诉发送方:我希望你(指发送方)下次发送的数据的第一个字节数据的编号为此确认号

    • 数据偏移:表示TCP报文段的首部长度,共4位,由于TCP首部包含一个长度可变的选项部分,需要指定这个TCP报文段到底有多长。它指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远。该字段的单位是32位(即4个字节为计算单位),4位二进制最大表示15,所以数据偏移也就是TCP首部最大60字节

    • URG:表示本报文段中发送的数据是否包含紧急数据。后面的紧急指针字段(urgent pointer)只有当URG=1时才有效

    • ACK:表示是否前面确认号字段是否有效。只有当ACK=1时,前面的确认号字段才有效。TCP规定,连接建立后,ACK必须为1,带ACK标志的TCP报文段称为确认报文段

    • PSH:提示接收端应用程序应该立即从TCP接收缓冲区中读走数据,为接收后续数据腾出空间。如果为1,则表示对方应当立即把数据提交给上层应用,而不是缓存起来,如果应用程序不将接收到的数据读走,就会一直停留在TCP接收缓冲区中

    • RST:如果收到一个RST=1的报文,说明与主机的连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。或者说明上次发送给主机的数据有问题,主机拒绝响应,带RST标志的TCP报文段称为复位报文段

    • SYN:在建立连接时使用,用来同步序号。当SYN=1,ACK=0时,表示这是一个请求建立连接的报文段;当SYN=1,ACK=1时,表示对方同意建立连接。SYN=1,说明这是一个请求
      建立连接或同意建立连接的报文。只有在前两次握手中SYN才置为1,带SYN标志的TCP报文段称为同步报文段

    • FIN:表示通知对方本端要关闭连接了,标记数据是否发送完毕。如果FIN=1,即告诉对方:“我的数据已经发送完毕,你可以释放连接了”,带FIN标志的TCP报文段称为结束报文段

    • 窗口大小:表示现在允许对方发送的数据量,也就是告诉对方,从本报文段的确认号开始允许对方发送的数据量,达到此值,需要ACK确认后才能再继续传送后面数据,由Window size value * Window size scaling factor(此值在三次握手阶段TCP选项Window scale协商得到)得出此值

    • 校验和:提供额外的可靠性

    • 紧急指针:标记紧急数据在数据字段中的位置

    • 选项部分:其最大长度可根据TCP首部长度进行推算。TCP首部长度用4位表示,选项部分最长为:(2^4-1)*4-20=40字节
      常见选项:
         最大报文段长度:Maxium Segment Size,MSS,通常1460字节
         窗口扩大:Window Scale
         时间戳: Timestamps

    • 1 最大报文段长度MSS(Maximum Segment Size)
      指明自己期望对方发送TCP报文段时那个数据字段的长度。比如:1460字节。数据字段的长度加上TCP首部的长度才等于整个TCP报文段的长度。MSS不宜设的太大也不宜设的太小。若选择太小,极端情况下,TCP报文段只含有1字节数据,在IP层传输的数据报的开销至少有40字节(包括TCP报文段的首部和IP数据报的首部)。这样,网络的利用率就不会超过1/41。若TCP报文段非常长,那么在IP层传输时就有可能要分解成多个短数据报片。在终点要把收到的各个短数据报片装配成原来的TCP报文段。当传输出错时还要进行重传,这些也都会使开销增大。因此MSS应尽可能大,只要在IP层传输时不需要再分片就行。在连接建立过程中,双方都把自己能够支持的MSS写入这一字段。 MSS只出现在SYN报文中。即:MSS出现在SYN=1的报文段中
      MTU和MSS值的关系:MTU=MSS+IP Header+TCP Header
      通信双方最终的MSS值=较小MTU-IP Header-TCP Header

    • 2 窗口扩大
      为了扩大窗口,由于TCP首部的窗口大小字段长度是16位,所以其表示的最大数是65535。但是随着时延和带宽比较大的通信产生(如卫星通信),需要更大的窗口来满足性能和吞吐率,所以产生了这个窗口扩大选项

    • 3 时间戳
      可以用来计算RTT(往返时间),发送方发送TCP报文时,把当前的时间值放入时间
      戳字段,接收方收到后发送确认报文时,把这个时间戳字段的值复制到确认报文中,当发送方收到确认报文后即可计算出RTT。也可以用来防止回绕序号PAWS,也可以说可以用来区分相同序列号的不同报文。因为序列号用32为表示,每2^32个序列号就会产生回绕,那么使用时间戳字段就很容易区分相同序列号的不同报文

    源端口和目标端口

    • 下层协议是为上层提供服务的,因此在传输层为了区分上层应用程序使用源端口和目标端口的方式区分应用程序不同的应用程序。

    • 端口号是用来区分同一台主机上的不同程序的,不同程序的唯一标准。

    • 端口号总共16位 --> 2^16=65535,意味着一台主机最多只能运行65535个与网络相关的应用程序。有些情况下一个应用程序会占用对个端口,一般也达不到这个应用程序,因此端口数足够使用。

    • 请求报文:
      目标端口 ==> 服务器,约定俗成
      源端口 ===> 客户端,随机分配

    • 响应报文:
      源端口 ==> 服务器,约定俗成
      目标端口 ===> 客户端,随机分配

    • 连接会话的区别:
      eg:
      ①使用xshell连接VMware中的Linux时,当xshell连接时选择ssh复制生成的终端属于会话。会话属于同一链路,会话不会分配端口。
      ②使用xshell再建立一个连接属于连接:连接会创建一条新的链路,重新分配端口。
      连接可以利用ss -tn查看

    [root@centos7 ~]# ss -tn
    State  Recv-Q Send-Q  Local Address:Port  Peer Address:Port              
    ESTAB  0      0       192.168.38.7:22      192.168.38.1:7915               
    ESTAB  0      52      192.168.38.7:22      192.168.38.1:1321
    
    • 常见服务与其对应的端口

      tcp
      http 80
      https 443
      ssh 22
      telnet 23
      ftp 21
      smtp 25
      pop 110
      imap 143
      mysql 3306
      oracle 1521
      sql server 1433 1434
    查询端口:(有时开发的服务需要对外提供服务,此时需要查询确认端口未被占用,
    此时可以查询哪些端口被占用)
    ~]vim /etc/services (/etc/services 记录了一些著名服务使用的协议和端口号)
    
    • TCP协议PORT
      1)传输层通过port号,确定应用层协议
      2)Port number:
      3)tcp:传输控制协议,面向连接的协议;通信前需要建立虚拟链路;结束后拆除链路
         0-65535
      4)udp:User Datagram Protocol,无连接的协议
         0-65535
      5)IANA:互联网数字分配机构(负责域名,数字资源,协议分配)
         0-1023:系统端口或特权端口(仅管理员可用) ,众所周知,永久的分配给固定的系统应用使用,22/tcp(ssh), 80/tcp(http), 443/tcp(https)
         1024-49151:用户端口或注册端口,但要求并不严格,分配给程序注册为某应用使用,1433/tcp(SqlServer), 1521/tcp(oracle),3306/tcp(mysql)11211/tcp/udp (memcached)
         49152-65535:动态端口或私有端口,客户端程序随机使用的端口
      其范围的定义:/proc/sys/net/ipv4/ip_local_port_range==》特定场合需要改此值;一般反向代理时此值需要改大(1024 65535)
    -l 是显示处于监听的端口;相当于默认开了哪些软件;
        [root@centos7 ~]# ss -tnl
        State   Recv-Q Send-Q   Local Address:Port   Peer Address:Port              
        LISTEN  0      128      *:111                *:*                  
        LISTEN  0      128      *:6000               *:*                  
        LISTEN  0      128      *:47220              *:*                  
        LISTEN  0      5        192.168.122.1:53     *:*                  
        LISTEN  0      128      *:22                 *:*                  
        LISTEN  0      128      127.0.0.1:631        *:*   
        .....
    
    当然面试时也经常会问哪个端口哪个程序正在使用:
        ①ss -tnlp (p选项)
        ②lsof -i :22(查询22端口哪个软件被占用)
    

    序号

    • 当数据报文比较大时,会涉及切包(因为在数据链路层帧结构中数据的最大是1500字节),在切包以后,每个包都有一个编号。

    • 序号的作用之一:当接收方接收到数据时,可以根据序号进行组合

    • 序号的作用之二:传输时,丢包有序号,以便减少重传的包的数量

    • 如何验证丢包?—>确认号

    确认号

    • 确认号是通信双方:接收方需要确认收到的数据包

    • 如何确认?
      ①eg:发送第 # 个包时,回复确认号为 #
      ②eg:发送第 # 个包时,回复确认号为 #+1,希望你下次发送下一个包

    • 网络中通信利用的是②这种机制

    • 报文包的个数总共32位有2^32个报文编号

    • 仅靠编号不能区分报文时,加时间戳

    • 接收方回应发送方:举例:


    确认号:ack < ==== > 序列号:seq (从上往下分析)
    ① client向server 请求:
    seq 10:表示 client 目前发送第10个包给 server
    ack 1: 表示 client 收到了 server 刚给它发的第0个包

    ②server向client 响应:
    seq 1: server 应 client 要求,将 1 包发送给 client
    ask 11:server 告诉 client ,client 刚给它的 10 包已收到

    ③…以此类推
    这种逻辑是每次都会收发确认,无形中效率不高…提高效率的方式:阶段性的回答收到还是未收到—>涉及窗口的问题

    窗口

    固定窗口

    • 窗口则是发多少个包确认一次

    • 若Window size=1,则表示一个包确认一次:

    • 窗口Window size=3 三个包确认一次

      这种窗口固定的逻辑逻辑也不是特别好,窗口固定,但是网络并不是稳定不变的

    滑动窗口

    • 工作中常用滑动窗口

      发送方< ==== >接收方
      原理:刚开始发送方会假设接收方一次能接受 # 个数据包,接受方回应发送方能收具体的数据包(若全收,发送方将增大#值,再试)此时相当于双方协商。当然发送过程根据不然的网络状态还会进行实时调整,因此TCP可以进行流量控制。

    • 目前在tcp包头中,窗口总共16位,则一次性的的报文最大为2^16=65536,但是随着网络带宽的增加,还是显得有点小。

    • 引入Window size scaling factor 以便扩大窗口大小。

    • 窗口扩大因子(Window size scaling factor )此值是在通信双方第一次通信时协商出来的,因子大小是固定的,但是窗口大小是变化的

    • 通信双方可能各有各自的因子,传输时=自己的因子大小*每次发送的窗口大小

    数据偏移

    • 数据报文的头部有多长,TCP报文头部大小并不固定,其中部分内容是可选的。

    • TCP报文头部的固定内容:每一行32bit(4字节)* 5行 =20字节

    • 可变部分:

    保留

    • 保留 - 保留了一部分数据位,空着的,目前未使用

    校验和

    • 校验数据是否被破坏

    紧急指针

    选项部分

    • 常见选项

    • 最大报文段长度:Maxium Segment Size,MSS,通常1460字节
         此最大报文长度是根据帧的数据位最大为1500,帧的数据位包括了网络层的头部和传输层的头部(各20字节固定长度)

    • 窗口扩大:Window Scale

    • 时间戳: Timestamps

    六个特殊标志

    • 在保留位之后是六个特殊标记,这六个标记分别的作用为:

    • URG: 表示紧急指针(urgent pointer)中内容是否有效:表示的是固定长度的最后一个紧急指针(16bit),如果此处URG=1,则紧急指针有效,URG=0则紧急指针的内容无效

    • RST:reset:若RST=1则表示与主机的连接出现了严重故障,需要重新建立连接;RST标志的TCP报文段称为复位报文段

    • PSH:表示网卡收到应用程序发过来的数据以后,默认情况将放置在内核中TCP缓冲区中,等待一段时间再将数据复制至应用程序。若PSH=1则表示立即将数据传给应用程序不再缓存;若PSH=0则表示默认情况

    • 重点掌握以下三个特殊标志:

    • ACK、SYN、FIN与建立TCP的通信息息相关,主机利用TCP协议进行通信之前需要建立TCP连接,建立连接的作用:确保通信双方可以进行安全可靠的通信。

    三次握手

    • 建立连接的过程一般被称为TCP的三次握手:

      三次握手的实现:如上图所示
      通常未进行通信过的两个主机,第一次发起请求的一般为客户端
      seq为序号 ack为确认号 大写ACK SYN FIN为三个特殊标记
         ①第一次发起请求时:client 设置 SYN=1 seq=x
        
         抓包软件可看到tcp请求连接建立的标志位SYN=1
         ② server收到时立即回应:server 回应 SYN=1 ACK=1 seq=y ack=x+1
         ③ client收到是立即回应:client 回应 ACK=1 seq=x+1 ack=y+1
         ④以上①②③ TCP三次握手就成功啦,建立连接,进行数据通信

    • 在TCP三次握手时,两个主机的网络连接状态是有变化的:
         ①server端必须事先将能够接受client服务的端口处于LISTEN状态。
         ②在访问server之前,client的随机端口也未被打开,当client去访问server时,随机端口打开,发起TCP建立连接请求,此时client的网络状态自动变为SYN-SENT状态。
         ③server端收到client端的连接建立请求后,server的网络状态由listen – > SYN-RCVD。
         ④client发送连接确认后,client的网络状态由 SYN-SENT --> ESTAB-LISHED。
         ⑤ server 再次收到连接确认时,server的网络状态有SYN-RCVD --> ESTAB-LISHED。
         server : LISTEN --> SYN-RCVD --> ESTAB-LISHED
         client : SYN-SENT --> ESTAB-LISHED

    四次挥手

    • TCP的四次挥手

    • 断开连接请求:可以是client 也可以是server

      图中当server端收到client的断开请求时,可能涉及到传输的数据没有传完,因此server端不会立即同意断开请求,可以继续给client端发送数据。此阶段数据传输是单向的(半双工,半关闭)
      当server端同意断开请求连接时,client的网络状态并未立即切换,因为先发的报文并不一定比server同意断开请求先到,需要等待2MSL(报文最长存活时间)时间,确认server端的数据全部接收后,才会改变网络状态。

    有限状态机FSM:Finite State Machine

    • CLOSED 没有任何连接状态

    • LISTEN 侦听状态,等待来自远方TCP端口的连接请求

    • SYN-SENT 在发送连接请求后,等待对方确认

    • SYN-RECEIVED 在收到和发送一个连接请求后,等待对方确认

    • ESTABLISHED 代表传输连接建立,双方进入数据传送状态

    • FIN-WAIT-1 主动关闭,主机已发送关闭连接请求,等待对方确认

    • FIN-WAIT-2 主动关闭,主机已收到对方关闭传输连接确认,等待对方发送关闭传输连接请求

    • TIME-WAIT 完成双向传输连接关闭,等待所有分组消失

    • CLOSE-WAIT 被动关闭,收到对方发来的关闭连接请求,并已确认

    • LAST-ACK 被动关闭,等待最后一个关闭传输连接确认,并等待所有分组消失

    • CLOSING 双方同时尝试关闭传输连接,等待对方确认

    有限状态机

    • 客户端先发送一个FIN给服务端,自己进入了FIN_WAIT_1状态,这时等待接收
      服务端的报文,该报文会有三种可能:
      ①只有服务端的ACK
      ②只有服务端的FIN
      ③基于服务端的ACK,又有FIN
    • 1、只收到服务器的ACK,客户端会进入FIN_WAIT_2状态,后续当收到服务端的FIN时,回应发送一个ACK,会进入到TIME_WAIT状态,这个状态会持续2MSL(TCP报文段在网络中的最大生存时间, RFC 1122标准的建议值是2min).客户端等待2MSL,是为了当最后一个ACK丢失时,可以再发送一次。因为服务端在等待超时后会再发送一个FIN给客户端,进而客户端知道ACK已丢失
    • 2、只有服务端的FIN时,回应一个ACK给服务端,进入CLOSING状态,然后接收到服务端的ACK时,进入TIME_WAIT状态
    • 3、同时收到服务端的ACK和FIN,直接进入TIME_WAIT状态

    客户端的典型状态转移

    • 客户端通过connect系统调用主动与服务器建立连接connect系统调用首先给服务器发送一个同步报文段,使连接转移到SYN_SENT状态

    • 此后connect系统调用可能因为如下两个原因失败返回:

    • 1、如果connect连接的目标端口不存在(未被任何进程监听),或者该端口仍被处于TIME_WAIT状态的连接所占用(见后文),则服务器将给客户端发送一个复位报文段,connect调用失败。

    • 2、如果目标端口存在,但connect在超时时间内未收到服务器的确认报文段,则connect调用失败。

    • connect调用失败将使连接立即返回到初始的CLOSED状态。如果客户端成功收到服务器的同步报文段和确认,则connect调用成功返回,连接转移至ESTABLISHED状态

    • 当客户端执行主动关闭时,它将向服务器发送一个结束报文段,同时连接进入FIN_WAIT_1状态。若此时客户端收到服务器专门用于确认目的的确认报文段,则连接转移至FIN_WAIT_2状态。当客户端处于FIN_WAIT_2状态时,服务器处于CLOSE_WAIT状态,这一对状态是可能发生半关闭的状态。此时如果服务器也关闭连接(发送结束报文段),则客户端将给予确认并进入TIME_WAIT状态

    • 客户端从FIN_WAIT_1状态可能直接进入TIME_WAIT状态(不经过FIN_WAIT_2状态),前提是处于FIN_WAIT_1状态的服务器直接收到带确认信息的结束报文段(而不是先收到确认报文段,再收到结束报文段)

    • 处于FIN_WAIT_2状态的客户端需要等待服务器发送结束报文段,才能转移至TIME_WAIT状态,否则它将一直停留在这个状态。如果不是为了在半关闭状态下继续接收数据,连接长时间地停留在FIN_WAIT_2状态并无益处。连接停留在FIN_WAIT_2状态的情况可能发生在:客户端执行半关闭后,未等服务器关闭连
      接就强行退出了。此时客户端连接由内核来接管,可称之为孤儿连接(和孤儿
      进程类似)

    • Linux为了防止孤儿连接长时间存留在内核中,定义了两个内核参数:
      /proc/sys/net/ipv4/tcp_max_orphans 指定内核能接管的孤儿连接数目
      /proc/sys/net/ipv4/tcp_fin_timeout 指定孤儿连接在内核中生存的时间

    展开全文
  • TCP 报文格式及TCP Flags

    万次阅读 2019-04-16 11:51:19
    (一)前言 TCP 是一个基于连接的四层协议,提供全双工地,...(二)TCP 报文格式(rfc793) 各个Field说明: 源端口(Source Port):长度为16 bits(2个字节)。源端口。 目的端口(Destination Port):长...

    (一)前言
           TCP 是一个基于连接的四层协议,提供全双工地,可靠地传输系统。它能够保证数据被远程主机接收。并且能够为高层协议提供flow-controlled 服务。

    (二)TCP 报文格式(rfc793)  

    各个Field说明:

        源端口(Source Port):长度为16 bits(2个字节)。源端口。
        目的端口(Destination Port):长度为16 bits(2个字节)。目的端口。
        序列号(Sequence Number):长度为32 bits(4个字节)。指定了当前数据分片中分配给第一字节数据的序列号。在TCP传输流中每一个字节为一个序号。如果TCP报文中flags标志位为SYN,该序列号表示初始化序列号(ISN),此时第一个数据应该是从序列号ISN+1开始。
        确认序列号(Acknowledgment Number):长度为32bits(4个字节)。表示TCP发送者期望接受下一个数据分片的序列号。该序号在TCP分片中Flags标志位为ACK时生效。序列号分片的方向和流的方向同方向,而确认序列号分片方向和流方向反方向。

        数据偏移或首部长度(Data Offset/Header Length): 长度为4bits。数据偏移也叫首部长度。因为首部长度实际也说明了数据区在分片中的起始偏移值。它表示TCP头包含了多少个32-bit的words。因为4bits在十进制中能表示的最大值为15,32bits表示4个字节,那么Data Offset的最大可表示15*4=60个字节。所以TCP报头长度最大为60字节。如果options fields为0的话,报文头长度为20个字节。
        预留字段(Reserved field):长度为6bits。值全为零。预留给以后使用。
        标志位(Flags): 长度为6bits。表示TCP包特定的连接状态。一个标签位占一个bit,从低位到高位值依次为FIN,SYN,RST,PSH,ACK,URG。新定义的TCP头还扩展了ECE,CWR,NS.
        窗口(Window):长度16bits(2个字节)。表示滑动窗口的大小,用来告诉发送端接收端的buffer space的大小。接收端buffer大小用来控制发送端的发送数据数率,从而达到流量控制。最大值为65535.
        校验和(Checksum):长度16bits(2个字节)。用来检查TCP头在传输中是否被修改。
        紧急指针(Urgent pointer):长度为16bits(2个字节)。表示TCP片中第一个紧急数据字节的指针。只有当URG标志置1时紧急指针才有效。
        选项和填充(Option和pading):可变长度。表示TCP可选选项以及填充位。当选项不足32bits时,填充字段加入额外的0填充。
        数据(Data):长度可变。用来存储上层协议的数据信息。可以为空。比如在连接建立和连接中止时。

        TCP 采用全双工模式,在连接建立后和连接中止前进行数据传输,数据传输是单向的,从发送端传输给接受端。TCP通过序列号能够保证数据被接受端接受。TCP建立连接是通过三次握手的方式来建立连接的。

    (三) TCP Flags

        TCP 在连接过程中,通过Flags标志位来表示传输过程中的连接状态。因此可以通过标志位来进行问题定位或者控制指定的连接是否提交。TCP 三次握手过程如下:

        对于旧版本的TCP头定义,Flags有6bits,新版TCP头对flags扩展了3bits。每个TCP flag对应于1bit位。所以旧版TCP头flags值有6个,新版扩展了3个值。从低位到高位分别是:FIN,SYN,RST,PSH,ACK,URG,ECE,CWR,NS。

        旧版TCP Flags字段:

        新版TCP Flags字段:

    Flags值说明:

        FIN: "finished"简写。表示发送者以及发送完数据。通常用在发送者发送完数据的最后一个包中。
        SYN: "Synchronisation"简写。表示三次握手建立连接的第一步,在建立连接时发送者发送的第一个包中设置flag值为SYN。
        RST: "reset"简写。重置连接标志,用于重置由于主机崩溃或其他原因而出现错误的连接。或者发送包发送到一个不是期望的                  目的主机时,接收端发送reset 重置连接标志的包。
        PSH: "push"简写。通知接收端处理接收的报文,而不是将报文缓存到buffer中。
        ACK: "Acknowledgment"简写。表示包已经被成功接收。
        URG: "urgent"简写。通知接收端处理在处理其他包前优先处理接收到的紧急报文(urgent packets)。详见RFC6093。
        ECE: "ECN-Echo"简写。ECN表示Explicit Congestion Notification。表示TCP peer有ECN能力。详见RFC3168。
        CWR: "Congestion Window Reduced"简写。发送者在接收到一个带有ECE flag包时,将会使用CWR flag。 详见RFC3168。
        NS: "nonce sum"简写。该标签用来保护不受发送者发送的突发的恶意隐藏报文的侵害。详见 RFC 3540。

    (四) 使用tcpdump抓取响应flag值得报文

        因为TCP Flags 位于TCP头的第14个字节中。所有可以通过如下命令进行抓取:

        抓取FIN包: tcpdump -i eth0 "tcp[13] & 1"  -ennnv
        抓取SYN包: tcpdump -i eth0 "tcp[13] & 2" -ennnv
        抓取RST包: tcpdump -i eth0 "tcp[13] & 4" -ennnv
        抓取PSH包: tcpdump -i eth0 "tcp[13] & 8" -ennnv
        抓取ACK包: tcpdump -i eth0 "tcp[13] & 16" -ennnv
        抓取URG包: tcpdump -i eth0 "tcp[13] & 32"  -ennnv

     

    参考:
        https://tools.ietf.org/html/rfc793
        https://tools.ietf.org/html/rfc3168
        https://tools.ietf.org/html/rfc3540

    展开全文
  • TCP报文发送接收测试工具

    热门讨论 2013-06-04 15:53:47
    TCP报文接收发送测试工具,可模拟客户端,也可模拟服务器端,可自动发送报文,对用来调试TCP报文传输调试是个非常好的测试工具。
  • 使用wireshark这款软件来分析TCP包,TCP报文为了方便读者复现,直接使用官网提供的包文件说明 准备TCP分析报文 从wireshark官网下载TCP分析包:200722_win_scale_examples_anon.pcapng,使用wireshark打开200722_win...
  • TCP报文格式

    万次阅读 多人点赞 2014-06-10 16:21:22
    TCP(Transmission Control Protocol)传输控制协议是一种面向连接的、可靠的、基于字节流的传输层协议TCP报文格式:源端口号(2字节): d5 df(54751)目的端口号(2字节): 22 b8(8888)TCP报头中的源端口号...
  • TCP报文段首部结构分析

    千次阅读 2019-09-02 20:37:08
    TCP报文段结构分析 TCP虽然是面向字节流的,但TCP传送的数据单元却是报文段。 TCP报文段如APR报文、IP数据报一样,也是由首部与数据区域组成,TCP首部内容很丰富,各个字段都有特定的含义,一般来说TCP首部只有20个...
  • TCP报文

    千次阅读 2019-04-11 13:26:09
    TCP是在传输的时候的数据单元是TCP报文段,TCP报文段分为两部分,首部和数据两部分,首部前20个字节固定,后面有4N个字节(N是整数)根据需要增加,因此TCP首部的最小字节是20,首部固定部分分为一下几种: ...
  • TCP报文段详解

    千次阅读 2018-11-30 17:44:43
    tcp报文段 源端口&amp;amp;目的端口 2字节 (tcp的分用功能以端口实现) 序号 4字节 tcp三次握手中的seq,表示tcp数据段发送的第一个字节的序号,范围[0,2^32 - 1],即mod 2^32; 例如,seq = 201,携带的数据有...
  • TCP报文格式详解

    万次阅读 多人点赞 2017-02-27 11:19:13
    TCP报文是TCP层传输的数据单元,也叫报文段。 端口号:用来标识同一台计算机的不同的应用进程。 源端口:源端口和IP地址的作用是标识报文的返回地址。 目的端口:端口指明接收方计算机上的应用程序接口。 TCP报头...
  • TCP报文之-tcp dup ack 、tcp Out-of-Order

    万次阅读 多人点赞 2016-12-20 11:25:16
    使用WireShark抓包,选择TCP报文,TCP是一种安全的协议,在网络出现状况时也能安全稳定的传输数据,但是在网络出现问题时tcp报文中会有很多中情况导致报文重传或者是重组。现在就在报文中遇到的几个问题来详细说明...
  • tcp报文格式

    千次阅读 2013-04-17 09:41:15
    TCP报文格式 TCP报文是TCP层传输的数据单元,也称为报文段。 TCP报文首部格式 l 源端口(Source Port):16位的源端口字段包含初始化通信的端口号。源端口和IP地址的作用是标识报文的返回...
  • TCP报文段的首部格式

    2019-07-07 18:21:36
    一个TCP报文段分为首部和数据两部分,而TCP的全部功能都体现在它首部中各字段的作用。TCP报文段首部的前20个字节是固定的,后面有4n个字节是根据需要而增加的选项(n是整数)。因此TCP首部的最小长度是20字节。 ...
  • TCP报文丢失

    千次阅读 2017-08-09 22:11:00
    主机 A 向主机 B 连续发送了两个 TCP 报文段,其序号分包是 70 和 ... 答案为70,收发两端各有两个字节流,TCP报文的序列号可以看作向对方发送字节流的起始位置,确认号可以看作他确认对方当前序号之前的字节
  • TCP报文头详解

    千次阅读 2020-04-20 23:39:49
    TCP报文是TCP层传输的数据单元,也叫报文段。 1、端口号 用来标识同一台计算机的不同的应用进程。 16位源端口(Source Port):16位的源端口字段包含初始化通信的端口号。源端口和IP地址的作用是标识报文的返回地址...
  • TCP报文段结构

    千次阅读 2017-05-02 19:36:31
    TCP协议的特点TCP是可靠的、面向连接、面向字节流、支持双工(客户端和服务器端可以互相传输数据)、支持并发连接、提供确认重传与拥塞控制的传输层...如下图所示,为TCP报文段的结构的展示图: 下面我们,一一介绍
  • TCP报文段格式

    千次阅读 2018-06-28 22:14:19
    三次握手就是一次TCP建立链接的过程四次挥手就是一次TCP断开的过程所以在学习三次握手四次挥手之前先了解一下TCP报文段的格式源端口(2字节):发送端应用程序的端口号,与源IP地址确定一个唯一地址目的端口(2字节...
  • tcp报文由tcp header和tcp数据组成。 tcp header 的最大长度为60字节,而必须要有的固定长度也就是图一的前5层的20字节,每层占有32bit,也就是32/8=4字节,5层,5*4 = 20字节,那么第六层的可选项和填充也...
  • TCP报文段、数据包、帧关系 首先简要了解他们之间关系,想必会增加你的兴趣。请先阅读文章一张图弄懂TCP报文段、数据包、帧之间的关系 一、TCP报文TCP报文段在传输层生成,文件数据在传输层被切割为不同的数据段...
  • TCP报文段头部格式

    千次阅读 2016-08-25 00:21:09
    一个TCP报文段分为首部和数据两个部分。TCP报文段首部的前20个字节是固定的,后面有4n字节是根据需要增加的选项。TCP首部的最小长度是20字节,最大长度是60字节。 下面介绍各个字段: 源端口和目的端口:各占2个...
  • 文章目录1.TCP协议特点2.TCP报文段的首部格式3.TCP连接管理(1)连接的建立 - - - 三次握手(2)SYN泛洪攻击4.TCP连接释放----四次握手5.TCP连接建立和释放的总结如下 1.TCP协议特点 2.TCP报文段的首部格式 TCP...
  • TCP报文格局详解

    千次阅读 2016-12-22 13:29:54
     TCP报文格局 TCP报文段首部(20个字节)  源端口和目标端口:各占2个字节,16比特的端标语加上32比特的IP地址,共同构成相当于传输层办事接见点的地址,即“插口”;  这些端口可用来将若干高层和谈向...
  • tcp报文黏连及解决方法

    千次阅读 2018-10-23 14:48:23
    TCP报文粘连就是,本来发送的是多个TCP报文,但是在接收端受到的却是一个报文,把多个报文合成了一个报文。 TCP报文粘连的原因: 1.TCP协议采用了Nagle算法  Nagle算法产生的背景是,当时为了解决发送多个非常小...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 178,692
精华内容 71,476
关键字:

tcp报文