位于: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_MIN 1
#define TCP_PRIO_NORMAL 64
#define TCP_PRIO_MAX 127
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()函数.