物联网LWIP网络开发TCP/IP设计原理12.4TCP数据结构

TCP数据结构

TCP报文封装

IP协议

物联网LWIP网络开发TCP/IP设计原理12.4TCP数据结构_第1张图片

TCP协议

物联网LWIP网络开发TCP/IP设计原理12.4TCP数据结构_第2张图片

tcp_hdr

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状态机封装

enum tcp_state {
  CLOSED      = 0,
  LISTEN      = 1,
  SYN_SENT    = 2,
  SYN_RCVD    = 3,
  ESTABLISHED = 4,
  FIN_WAIT_1  = 5,
  FIN_WAIT_2  = 6,
  CLOSE_WAIT  = 7,
  CLOSING     = 8,
  LAST_ACK    = 9,
  TIME_WAIT   = 10
};

TCP协议控制块

IP_PCB

/** This is the common part of all PCB types. It needs to be at the
   beginning of a PCB type definition. It is located here so that
   changes to this common part are made in one location instead of
   having to change all PCB structs. */
#define IP_PCB \
  /* ip addresses in network byte order */ \
  ip_addr_t local_ip; \
  ip_addr_t remote_ip; \
   /* Socket options */  \
  u8_t so_options;      \
   /* Type Of Service */ \
  u8_t tos;              \
  /* Time To Live */     \
  u8_t ttl               \
  /* link layer address resolution hint */ \
  IP_PCB_ADDRHINT

TCP_PCB_COMMON

/**
 * members common to struct tcp_pcb and struct tcp_listen_pcb
 lwip tcp协议控制块非常大,就导致我在监听的时候,不需要这么多,但是又需要其中一部分,就把公共的部分提取出来
 */
#define TCP_PCB_COMMON(type) \
  type *next; /* TCP 协议控制块的链表指针 */ \
  void *callback_arg; \
  enum tcp_state state; /* TCP 状态机 */ \
  u8_t prio; \
  /* 本地端口号 */ \
  u16_t local_port

tcp_pcb_listen


/** the TCP protocol control block for listening pcbs */
struct tcp_pcb_listen {
/** Common members of all PCB types */
  IP_PCB;
/** Protocol specific PCB members */
  TCP_PCB_COMMON(struct tcp_pcb_listen);

#if LWIP_CALLBACK_API
  /* 这是监听的协议控制块,当有客户端连接的时候,需要有个回调函数进行处理 */
  tcp_accept_fn accept;
#endif /* LWIP_CALLBACK_API */

#if TCP_LISTEN_BACKLOG
  //可同时监听的TCP最大连接数
  u8_t backlog;
  //已经接入,还未处理的连接数
  u8_t accepts_pending;
#endif /* TCP_LISTEN_BACKLOG */
};

tcp_pcb

/** the TCP protocol control block */
struct tcp_pcb {
/** common PCB members */
  IP_PCB;
/** protocol specific PCB members */
  TCP_PCB_COMMON(struct tcp_pcb);
  /* 目标端口号 */
  u16_t remote_port;
//tcp协议处理时,定义一些tcp的标志
tcpflags_t flags;
#define TF_ACK_DELAY   0x01U   /* 延时应答标志 */
#define TF_ACK_NOW     0x02U   /* 立刻应答标志 */
    
#define TF_INFR        0x04U   /* 快速回复标志 */
#define TF_CLOSEPEND   0x08U   /* 当FIN包发送失败时,这个标志会置位,同时重发是基于tcp_tmr定时器 */
#define TF_RXCLOSED    0x10U   /* 主动关闭接收,此标志位置位 */
#define TF_FIN         0x20U   /* 关闭本地连接(发送),此标志位置位 */

#define TF_NODELAY     0x40U   /* 关闭Nagle算法的标志位(在TCP通信时,加上缓冲延时算法)*/
#define TF_NAGLEMEMERR 0x80U   /* 启动nagle算法标志位*/
#if TCP_LISTEN_BACKLOG
#define TF_BACKLOGPEND 0x0200U /* 当置位时,增大backlog值*/
  /* 定时器相关 */
  //轮询定时器,在裸机程序中使用,其实就RAW接口
  u8_t polltmr, pollinterval;
  //最后一次操作pcb时间
  u8_t last_timer;
  //pcb中的基础定时器
  u32_t tmr;

  /* tcp接收相关的变量    接收窗口相关的成员变量 */
  u32_t rcv_nxt;   /* 下个要接收窗口序号*/
  tcpwnd_size_t rcv_wnd;   /* 接收窗口大小 */
  tcpwnd_size_t rcv_ann_wnd; /* 接收窗口大小用于通知目标机 */
  u32_t rcv_ann_right_edge; /* 宣布右边沿的窗口 */
    
    
   /* tcp发送相关的变量    发送窗口相关的成员变量  */
  u32_t snd_nxt;   /* 下个要发送的窗口序号*/
  u32_t snd_wl1, snd_wl2; /* 在下一次窗口更新之前的序号和应答序号 */
  u32_t snd_lbb;       /* 不能再发送的窗口索引 */
  tcpwnd_size_t snd_wnd;   /* 程序内部定义的发送窗口 */
  tcpwnd_size_t snd_wnd_max; /* 其实就是目标机的介绍窗口*/
  tcpwnd_size_t snd_buf;   /* 发送缓冲区的大小值*/

  /* 重发定时器 (协议交互,握手时) */
  s16_t rtime;
  s16_t rto;    /* retransmission time-out */
  u8_t nrtx;    /* number of retransmissions */
    
    

  u16_t mss;   /* 最大的段长度*/

  /* RTT传输时间,用于优化通讯链路使用*/
  u32_t rttest; /* RTT estimate in 500ms ticks */
  u32_t rtseq;  /* sequence number being timed */
  s16_t sa, sv; /* @todo document this */
   

    
    
  u32_t lastack; /*  最后一次应答序号 */
  /* 阻塞控制的变量 */
  tcpwnd_size_t cwnd;		//连接窗口
  tcpwnd_size_t ssthresh;	//慢连接的门限值


  /*  
  	实际的TCP数据段内容
  */
  struct tcp_seg *unsent;   /* 未发送的tcp数据段 */
  struct tcp_seg *unacked;  /* 发送完毕,单未应答的数据段*/
#if TCP_QUEUE_OOSEQ
  struct tcp_seg *ooseq;    /* 已经收到的数据段 */
#endif /* TCP_QUEUE_OOSEQ */

  struct pbuf *refused_data; /* 已经接收到的数据,并没有让应用层调用 */

#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
  struct tcp_pcb_listen* listener;
#endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */

#if LWIP_CALLBACK_API  // ----- RAW接口
  /* Function to be called when more send buffer space is available. */
  tcp_sent_fn sent;
  /* Function to be called when (in-sequence) data has arrived. */
  tcp_recv_fn recv;
  /* Function to be called when a connection has been set up. */
  tcp_connected_fn connected;
  /* Function which is called periodically. */
  tcp_poll_fn poll;
  /* Function to be called whenever a fatal error occurs. */
  tcp_err_fn errf;
#endif /* LWIP_CALLBACK_API */
  /* 心跳检测相关的 */
  u32_t keep_idle;
#if LWIP_TCP_KEEPALIVE
  u32_t keep_intvl;
  u32_t keep_cnt;
#endif /* LWIP_TCP_KEEPALIVE */
  /* KEEPALIVE counter */
  u8_t keep_cnt_sent;
};

接收窗口

物联网LWIP网络开发TCP/IP设计原理12.4TCP数据结构_第3张图片

发送窗口

物联网LWIP网络开发TCP/IP设计原理12.4TCP数据结构_第4张图片

你可能感兴趣的:(lwIP网络,lwip,网络)