打印
[应用相关]

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

[复制链接]
842|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
木木guainv|  楼主 | 2018-9-15 22:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
原文网址:https://blog.csdn.net/zhzht19861011/article/details/6191480

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

#define tcp_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)

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

函数源码:

[cpp] view plain copy



  • /**
  • * 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连接放入已监听队列.


沙发
mmuuss586| | 2018-12-23 19:51 | 只看该作者
感谢分享;

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

146

主题

4098

帖子

5

粉丝