位于: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) { //没能成功分配内存
/* 尝试结束在TIME-WAIT状态下最老的连接 */
LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection/n"));
tcp_kill_timewait();
/* 再次尝试分配一个tcp_pcb */
pcb = memp_malloc(MEMP_TCP_PCB);
if (pcb == NULL) {
/* 尝试结束一个有效的连接, 该连接优先级小于等于新连接的 */
tcp_kill_prio(prio);
/* 再次尝试分配一个tcp_pcb */
pcb = memp_malloc(MEMP_TCP_PCB);
}
}
if (pcb != NULL) { //如果申请到一个pcb
/*将分配到的内存块设置成0 */
memset(pcb, 0, sizeof(struct tcp_pcb));
pcb->prio = TCP_PRIO_NORMAL;
/*用于发送的有效数据缓冲区大小(单位:字节) */
pcb->snd_buf = TCP_SND_BUF; //TCP_SND_BUF在opt.h中定义,默认256
pcb->snd_queuelen = 0; //用于发送的有效数据缓冲区空间大小(单位:tep_segs)
/*接收器窗口由rcv_wnd字段保存并且字段值在将要发送的TCP段中获取的 */
pcb->rcv_wnd = TCP_WND; //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()函数.