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

lwIP(V1.0.0) RAW API函数源码分析3----tcp_listen()函数

 
阅读更多

在lwip-x.x.x/src/core/tcp.h中定义:

#definetcp_listen(pcb)tcp_listen_with_backlog(pcb,TCP_DEFAULT_LISTEN_BACKLOG)

所以, tcp_listen(pcb)和tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG)是一回事. TCP_DEFAULT_LISTEN_BACKLOG在opt.h中定义,默认值为0xFF,指明最大允许的可等待TCP监听链接个数.

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

原型: struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)

功能:使指定的连接开始进入监听状态

函数源码:

/**
 * Set the state of the connection to be LISTEN, which means that it
 * is able to accept incoming connections. The protocol control block
 * is reallocated in order to consume less memory. Setting the
 * connection to LISTEN is an irreversible process.
 *设置连接进入LISTEN状态,这意味着这个连接能够接受传入的连接,为了消耗更少的内存,
协议控制块会被重新分配.设置连接进入LISTEN状态是一个不可逆转的过程
 * @param pcb the original tcp_pcb
 * @param backlog the incoming connections queue limit传入连接的队列限制
 * @return tcp_pcb used for listening, consumes less memory.
 *
 * @note The original tcp_pcb is freed(原始的tcp_pcb会被释放). This function therefore has to be
 *       called like this:
 *             tpcb = tcp_listen(tpcb);
 */
struct tcp_pcb *
tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
{
  struct tcp_pcb_listen *lpcb;

  LWIP_UNUSED_ARG(backlog);	// #define LWIP_UNUSED_ARG(x)  (void)x
  LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL);

  /* already listening? 是否应经处于监听?*/
  if (pcb->state == LISTEN) {
    return pcb;
  }
  lpcb = memp_malloc(MEMP_TCP_PCB_LISTEN);//申请一块内存
  if (lpcb == NULL) {
    return NULL;
  }
  lpcb->callback_arg = pcb->callback_arg;
  lpcb->local_port = pcb->local_port;
  lpcb->state = LISTEN;	//置监听标志位
  lpcb->so_options = pcb->so_options;
  lpcb->so_options |= SOF_ACCEPTCONN;
  lpcb->ttl = pcb->ttl;
  lpcb->tos = pcb->tos;
  ip_addr_set(&lpcb->local_ip, &pcb->local_ip);
  TCP_RMV(&tcp_bound_pcbs, pcb);
  memp_free(MEMP_TCP_PCB, pcb);	//释放原来的(原始的) PCB
#if LWIP_CALLBACK_API
  lpcb->accept = tcp_accept_null;		//默认回调函数
#endif /* LWIP_CALLBACK_API */
#if TCP_LISTEN_BACKLOG
  lpcb->accepts_pending = 0;
  lpcb->backlog = (backlog ? backlog : 1);
#endif /* TCP_LISTEN_BACKLOG */
  TCP_REG(&tcp_listen_pcbs.listen_pcbs, lpcb);	//将连接放入已监听队列
  return (struct tcp_pcb *)lpcb;
}

分析:这个函数从原理上看也比较简单,首先是做一些必要的检查,判断原始pcb是否已经处于连接状态,如果没有则申请一块tcp_pcb类型的内存,将原始的必要的pcb内容复制到新的pcb,设置新的pcb状态为LISTEN,释放原始的pcb,并将新pcb连接放入已监听队列.
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics