2009-5-11 LWIP现在我们正式开始进入对TCP处理过程被分割为六个功能函数的实现:tcp_input(), tcp_process(), tcp_receive()【用于TCP文件来分析一下:我们知道这里的函数都是被socket这个函数,当然这期间也做了不少工作,最主要的就是把发送数据的指针放到了msg长度
中
这个函数的最直接调用有以下几个:
available = tcp_sndbuf(conn->pcb.tcp);
err = tcp_write(conn->pcb.tcp, dataptr, len, conn->write_msg->msg.w.apiflags);
err = tcp_output_nagle(conn->pcb.tcp);
err = tcp_output(conn->pcb.tcp);
的重要性。
#define tcp_sndbuf(pcb) ((pcb)->snd_buf)
//
那就继续跟踪这个
pcb
的时候调用了
do_newconn
的话有以下代码
msg->conn->pcb.tcp = tcp_new();
<span times="" new="" roman';="" mso-hansi-font-family:="" 'times="" roman'"="" style="padding: 0px; margin: 0px; color: black; font-family: 宋体; ">哈哈,还记得吧,在前面我讨论到了这里,就没有再讨论了。嗯,现在开始吧。
* 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().
struct tcp_pcb * tcp_new(void)
{
return tcp_alloc(TCP_PRIO_NORMAL);
}
的
pcb
×××××××××××××××××××××××××××××××××××××××
【当然是
tcp
分别检查了
3
个
pcb
】、
tcp_tw_pcbs
【处于监听状态的
pcbs
函数更有意思,它分别检查了
4
【处于已经绑定但还没有连接或者监听
pcbs
相同的
pcb
链表中了。
对的,别的可以先不管,这就是我们要找的东西
pcb->snd_queuelen = 0;
pcb->rcv_wnd = TCP_WND;
pcb->rcv_ann_wnd = TCP_WND;
pcb->tos = 0;
pcb->ttl = TCP_TTL;
/* The send MSS is updated when an MSS option is received. */
pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
pcb->rto = 3000 / TCP_SLOW_INTERVAL;
pcb->sa = 0;
pcb->sv = 3000 / TCP_SLOW_INTERVAL;
pcb->rtime = -1;
pcb->cwnd = 1;
iss = tcp_next_iss();
pcb->snd_wl2 = iss;
pcb->snd_nxt = iss;
pcb->snd_max = iss;
pcb->lastack = iss;
pcb->snd_lbb = iss;
pcb->tmr = tcp_ticks;
pcb->polltmr = 0;
#if LWIP_CALLBACK_API
pcb->recv = tcp_recv_null;
#endif /* LWIP_CALLBACK_API */
/* Init KEEPALIVE timer */
pcb->keep_idle = TCP_KEEPIDLE_DEFAULT;
#if LWIP_TCP_KEEPALIVE
pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT;
pcb->keep_cnt = TCP_KEEPCNT_DEFAULT;
#endif /* LWIP_TCP_KEEPALIVE */
pcb->keep_cnt_sent = 0;
}
return pcb;
}
好了,下面接着走,该轮到
tcp_writ
e
】
err_t tcp_write(struct tcp_pcb *pcb, const void *data, u16_t len, u8_t apiflags)
{
/* connection is in valid state for data transmission? */
if (pcb->state == ESTABLISHED ||
pcb->state == CLOSE_WAIT ||
pcb->state == SYN_SENT ||
pcb->state == SYN_RCVD)
{
if (len > 0)
{
return tcp_enqueue(pcb, (void *)data, len, 0, apiflags, NULL, 0);
}
return ERR_OK;
}
else
{
return ERR_CONN;
}
}
下面的这个
tcp_enqueue
()函数以实现发送数据,接着
tcp_write
段,然后再把这些
TCP
咱们接着上面往下看,
tcp_output_nagle
来实现的。这个函数或许比
tcp_enqueue
。文档是这么解释的:
tcp_output
报头字段,接着就使用
ip_route<span times="" new="" roman';="" mso-hansi-font-family:="" 'times="" roman'"="" style="padding: 0px; margin: 0px; color: black; font-family: 宋体; ">或者
ip_output_if<span times="" new="" roman';="" mso-hansi-font-family:="" 'times="" roman'"="" style="padding: 0px; margin: 0px; color: black; font-family: 宋体; ">函数发送数据。
本文出自 “bluefish” 博客,请务必保留此出处http://bluefish.blog.51cto.com/214870/158415