zoukankan      html  css  js  c++  java
  • TCP close seq问题

    测试mt_hls一条流时,发现会话的时长总是对应不上。

    仔细观察发现:

    注意

      1.包1735 (客户端) 发送FIN 请求,seq = 2435582428

      2.包1736,1737,1738 (服务端)继续传输数据

         3.包1739服务端 回传 对 1735包 FIN 的ack 。 recv_ack =2435582429

         4.包1740 (客户端)发送 RST,seq = 2435582428, 这是不对的! seq应该 = 2435582429 故 包异常。

         5.包2319 (客户端)继续发送RST,seq= 2435582429, 此时包正常。 故此时的会话结束时间 记录为此刻的FRAME 的 echo time.

    附:tcp.c process_tcp 1228行附近

     if (
          ! (  !datalen && ntohl(this_tcphdr->th_seq) == rcv->ack_seq  )
          &&
          ( !before(ntohl(this_tcphdr->th_seq), rcv->ack_seq + rcv->window*rcv->wscale) ||
              before(ntohl(this_tcphdr->th_seq) + datalen, rcv->ack_seq)  
            )
         )  
          {
              printf("----> :%u + %d , %u 
    ",ntohl(this_tcphdr->th_seq), datalen,  rcv->ack_seq);
         return;
          }
    
      if ((this_tcphdr->th_flags & TH_RST)) {
        if (a_tcp->nids_state == NIDS_DATA) {
          struct lurker_node *i;
    
                printf("tcp_close NIDS_RESET time: %lf, ack:%u
    ", a_tcp->latest_tv.tv_sec + a_tcp->latest_tv.tv_usec / 1000000.0, a_tcp->client.ack_seq);
    
          a_tcp->nids_state = NIDS_RESET;
          for (i = a_tcp->listeners; i; i = i->next)
        (i->item) (a_tcp, &i->data);
        }
        nids_free_tcp_stream(a_tcp);
        return;
      }

    此代码片段 是做一个seq检验的。

    1. 包1740
    ! ( !datalen && ntohl(this_tcphdr->th_seq) == rcv->ack_seq )

    包1740 当前datalen 为0 且 th_seq (2435582428) 不等于 rcv->ack_seq(2435582429).

    且 before(ntohl(this_tcphdr->th_seq) + datalen, rcv->ack_seq), 2435582428 + 0 < 2435582429 成立

    此包丢弃。

    2.包2319

    此时TCP会话置为 NIDS_RESET状态, 关闭会话。



    注:
    序列号为当前端成功发送的数据位数,确认号为当前端成功接收的数据位数,SYN标志位和FIN标志位也要占1位

    序列号和确认号

    TCP会话的每一端都包含一个32位(bit)的序列号,该序列号被用来跟踪该端发送的数据量。每一个包中都包含序列号,在接收端则通过确认号用来通知发送端数据成功接收

    当某个主机开启一个TCP会话时,他的初始序列号是随机的,可能是0和4,294,967,295之间的任意值,然而,像Wireshark这种工具,通常显示的都是相对序列号/确认号,而不是实际序列号/确认号,相对序列号/确认号是和TCP会话的初始序列号相关联的。这是很方便的,因为比起真实序列号/确认号,跟踪更小的相对序列号/确认号会相对容易一些

    比如,在“包1”中,最初的相对序列号的值是0,但是最下方面板中的ASCII码显示真实序列号的值是0xf61c6cbe,转化为10进制为4129057982

    如果想要关闭相对序列号/确认号,可以选择Wireshark菜单栏中的 Edit -> Preferences ->protocols ->TCP,去掉Relative sequence number后面勾选框中的√即可



    参考:http://blog.csdn.net/a19881029/article/details/38091243
    http://blog.csdn.net/whuslei/article/details/6667471



  • 相关阅读:
    leetcode Convert Sorted List to Binary Search Tree
    leetcode Convert Sorted Array to Binary Search Tree
    leetcode Binary Tree Level Order Traversal II
    leetcode Construct Binary Tree from Preorder and Inorder Traversal
    leetcode[105] Construct Binary Tree from Inorder and Postorder Traversal
    证明中序遍历O(n)
    leetcode Maximum Depth of Binary Tree
    限制 button 在 3 秒内不可重复点击
    HTML 和 CSS 画三角形和画多边行基本原理及实践
    在线前端 JS 或 HTML 或 CSS 编写 Demo 处 JSbin 与 jsFiddle 比较
  • 原文地址:https://www.cnblogs.com/iclk/p/4540292.html
Copyright © 2011-2022 走看看