TCP报文段首部结构分析

TCP报文段首部结构

TCP虽然是面向字节流的,但TCP传送的数据单元却是报文段。

TCP报文段如APR报文、IP数据报一样,也是由首部数据区域组成,TCP首部内容很丰富,各个字段都有特定的含义,一般来说TCP首部只有20个字节,TCP报文段首部的前20个字节是固定的,后面有4N字节是根据需要而增加的选项字段(N是整数)。因此TCP首部的最小长度是20字节。

LwIP中,TCP首部采用一个名字叫tcp_hdr的结构体进行描述。此处用PACK_STRUCT_BEGINPACK_STRUCT_END宏定义禁止编译器对齐,因为在tcp首部中存在某些字段是以1字节对齐的。

PACK_STRUCT_BEGIN
struct tcp_hdr {
  PACK_STRUCT_FIELD(u16_t src);     /* 源端口 */
  PACK_STRUCT_FIELD(u16_t dest);    /* 目的端口 */
  PACK_STRUCT_FIELD(u32_t seqno);   /* 序号 */
  PACK_STRUCT_FIELD(u32_t ackno);   /* 确认序号 */
  PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);  /* 首部长度+保留位+标志位 */
  PACK_STRUCT_FIELD(u16_t wnd);     /* 窗口大小 */
  PACK_STRUCT_FIELD(u16_t chksum);  /* 校验和 */  
  PACK_STRUCT_FIELD(u16_t urgp);    /* 紧急指针 */
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END

TCP报文段首部结构分析_第1张图片
首部固定部分各字段的意义如下:

  • 每个TCP报文段都包含源主机目标主机的端口号,各占2个字节,用于寻找发送端和接收端应用线程,这两个值加上I P首部中的源I P地址和目标I P地址就能确定唯一一个TCP连接。

  • 序号字段占4字节,序号范围是[0,4294967295],序号增加到4284967295后,下一个序号就又回到0,主要是用来标识从TCP发送端TCP接收端发送的数据字节流,它的值表示在这个报文段中的第一个数据字节所处位置吗,根据接收到的数据区域长度,就能计算出报文最后一个数据所处的序号,因为TCP会对发送或者接收的数据进行编号(按字节流的形式),那么使用序号对每个字节进行计数,就能很轻易管理这些数据。TCP报文段的初始序列号(ISN)是随机的,可能是0~4294967295之间的任意值.

  • 既然TCP给每个传输的字节都了编号,那么确认序号就包含接收端所期望收到的下一个序号,因此,确认序号应当是上次已成功收到数据的最后一个字节序号加 1。当然,只有ACK标志为 1时确认序号字段才有效,TCP为应用层提供全双工服务,这意味数据能在两个方向上独立地进行传输,因此确认序号通常会与反向数据(即接收端传输给发送端的数据)封装在同一个报文中(即捎带),所以连接的每一端都必须保持每个方向上的传输数据序号准确性

  • 首部长度字段占据4bit空间(或者称数据偏移字段),它指出了TCP报文段首部长度,以字节为单位,最大能记录15*4=60字节的首部长度,因此,TCP报文段首部最大长度为60字节。在首部长度字段后接下来有6bit空间是保留未用的。

  • TCP报文段首部的标志字段

  • URG:首部中的紧急指针字段标志,如果是1表示紧急指针字段有效。

  • ACK:首部中的确认序号字段标志,如果是1表示确认序号字段有效。

  • PSH:该字段置一表示接收方应该尽快将这个报文段交给应用层。

  • RST:重新建立TCP连接。

  • SYN:用同步序号发起连接。

  • FIN:中止连接。

  • TCP的流量控制由连接的每一端通过声明的窗口大小来提供,窗口大小为字节数,起始于确认序号字段指明的值,这个值是接收端正期望接收的数据序号,发送方根据窗口大小调整发送数据,以实现流量控制。窗口大小是一个占据16 bit空间的字段,因而窗口最大为 65535字节,当接收方告诉发送方一个大小为0的窗口时,将完全阻止发送方的数据发送。

  • 只有当URG标志置1时紧急指针才有效,紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。简单来说,本TCP报文段的紧急数据在报文段数据区域中,从序号字段开始,偏移紧急指针的值结束。

使用wireshark抓包工具分析:
TCP报文段首部结构分析_第2张图片

你可能感兴趣的:(LwIP)