`
yidongkaifa
  • 浏览: 4061983 次
文章分类
社区版块
存档分类
最新评论

LwIP(V1.0.0) RAW API函数源码分析1----tcp_new()函数

 
阅读更多

位于:lwip/src/core/tcp.c

原型:struct tcp_pcb *tcp_new(void)

功能:常见一个TCP协议控制块但并不把它放到任何TCP PCB列表,直到使用tcp_bind()函数绑定.

代码:

/**
 * Creates a new TCP protocol control block but doesn't place it on
 * any of the TCP PCB lists.
 * The pcb is not put on any list until binding using tcp_bind().
 *
 * @internal: Maybe there should be a idle TCP PCB list where these
 * PCBs are put on. Port reservation using tcp_bind() is implemented but
 * allocated pcbs that are not bound can't be killed automatically if wanting
 * to allocate a pcb with higher prio (@see tcp_kill_prio())
 *
 * @return a new tcp_pcb that initially is in state CLOSED
 */
struct tcp_pcb *
tcp_new(void)
{
  return tcp_alloc(TCP_PRIO_NORMAL);	//分配一个新的tcp_pcb结构,正常优先级
}

分析:

1. TCP_PRIO_NORMAL:新pcb的优先级

在tcp.h中有以下定义:

#define TCP_PRIO_MIN1

#define TCP_PRIO_NORMAL 64

#define TCP_PRIO_MAX127

2.tcp_alloc函数:分配一个新的tcp_pcb结构.

该函数源代码:

/**
 * Allocate a new tcp_pcb structure.
 *
 * @param prio priority for the new pcb
 * @return a new tcp_pcb that initially is in state CLOSED
 */
struct tcp_pcb *
tcp_alloc(u8_t prio)
{
  struct tcp_pcb *pcb;
  u32_t iss;

  pcb = memp_malloc(MEMP_TCP_PCB);	//申请内存
  if (pcb == NULL) {		//没能成功分配内存
    /* Try killing oldest connection in TIME-WAIT. */
    LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection/n"));
    tcp_kill_timewait();		//尝试结束最老的连接
    /* Try to allocate a tcp_pcb again. */
    pcb = memp_malloc(MEMP_TCP_PCB);	//再次尝试分配一个tcp_pcb
    if (pcb == NULL) {
      /* Try killing active connections with lower priority than the new one. */
      tcp_kill_prio(prio);//尝试结束一个活动的但优先级低于要申请的tcp_pcb连接
      /* Try to allocate a tcp_pcb again. */
      pcb = memp_malloc(MEMP_TCP_PCB);
    }
  }
  if (pcb != NULL) {	//如果申请到一个pcb
    memset(pcb, 0, sizeof(struct tcp_pcb));	//将分配到的内存块设置成0
    pcb->prio = TCP_PRIO_NORMAL;
    pcb->snd_buf = TCP_SND_BUF;	//用于发送的有效数据缓冲区大小(单位:字节)
				// TCP_SND_BUF在opt.h中定义,默认256
    pcb->snd_queuelen = 0;	//用于发送的有效数据缓冲区空间大小(单位:tep_segs)
    pcb->rcv_wnd = TCP_WND;	//接收器窗口由rcv_wnd字段保存并且字段值是在将要发送的TCP段中获取的
				// TCP_WND在opt.h中定义,默认2048
    pcb->rcv_ann_wnd = TCP_WND;	//宣称的接收窗口
    pcb->tos = 0;		//服务类型
    pcb->ttl = TCP_TTL;		//生存时间
				//TCP_TTL在opt.h中定义,默认255
    /* The send MSS(发送段的最大容量) is updated when an MSS option is received. */
    pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; // TCP_MSS在opt.h中定义,默认128,是一个非常保守的默认值.
    pcb->rto = 3000 / TCP_SLOW_INTERVAL;	//超时重传时间
					// TCP_SLOW_INTERVAL在tcp.h中定义,默认值是500
    pcb->sa = 0;			//平均往返时间
    pcb->sv = 3000 / TCP_SLOW_INTERVAL;	//平均时间差
    pcb->rtime = -1;			//重传时间
    pcb->cwnd = 1;			//连接的当前阻塞窗口值
    iss = tcp_next_iss();  		//为新连接计算一个初始序号,最初值为6510
    pcb->snd_wl2 = iss;
    pcb->snd_nxt = iss;			//下一个要发送的序号
    pcb->snd_max = iss;		        //最高发送序号
    pcb->lastack = iss;			//收到的最后一个ACK包的序列号
    pcb->snd_lbb = iss;			//传输队列最后一个字节的顺序编号
    pcb->tmr = tcp_ticks;		//当指定的时间到时,连接应取消

    pcb->polltmr = 0;			//轮询时间

#if LWIP_CALLBACK_API		//在opt.h中定义,为1表示直接使用回调函数
    pcb->recv = tcp_recv_null;	// tcp_recv_null:默认接收回调函数
#endif /* LWIP_CALLBACK_API */

    /* Init KEEPALIVE timer 初始化持续连接时间*/
    pcb->keep_idle  = TCP_KEEPIDLE_DEFAULT;	//默认两小时,定义在tcp.h中

#if LWIP_TCP_KEEPALIVE	//在opt.h中定义,默认为0
    pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT;
    pcb->keep_cnt   = TCP_KEEPCNT_DEFAULT;
#endif /* LWIP_TCP_KEEPALIVE */

    pcb->keep_cnt_sent = 0;		// KEEPALIVE计数器
  }
  return pcb;
}

总结一下, tcp_alloc函数通过动态申请一块内存并初始化它,之后将这块内存的首地址返回给tcp_new()函数.
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics