lwIP(V1.3.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_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()函数.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值