打印
[应用相关]

lwIP(V1.3.0) RAW API函数源码分析2----tcp_bind()函数

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

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

原型: err_t  tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)

功能:绑定连接到一个本地端口号和IP地址.

函数源码:

[cpp] view plain copy



  • /**
  • * Binds the connection to a local port number and IP address. If the
  • * IP address is not given (i.e., ipaddr == NULL), the IP address of
  • * the outgoing network interface is used instead.
  • *IP地址没有给出(即ipaddr==NULL),则IP地址由输出网络接口代替
  • * @param pcb the tcp_pcb to bind (no check is done whether this pcb is
  • *        already bound!)
  • * @param ipaddr the local ip address to bind to (use IP_ADDR_ANY to bind
  • *        to any local address
  • * @param port the local port to bind to
  • * @return ERR_USE if the port is already in use
  • *         ERR_OK if bound 成功绑定
  • */  
  • err_t  
  • tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)  
  • {  
  •   struct tcp_pcb *cpcb;  
  •   
  •   LWIP_ERROR("tcp_connect: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);   
  •   
  •   if (port == 0) {  
  •     port = tcp_new_port();  //返回一个新的(自由的)本地TCP端口号  
  •   }  
  •   /* Check if the address already is in use. */  
  •   /* Check the listen pcbs. */  
  • /* 检查*/  
  •   for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs;/*注1 */  
  •       cpcb != NULL; cpcb = cpcb->next) {  
  •     if (cpcb->local_port == port) {  
  •       if (ip_addr_isany (&(cpcb->local_ip)) /*已监听pcb列表中IP地址全为0或没有分配IP地址,则函数返回1*/||  
  •           ip_addr_isany(ipaddr) /*检验参数IP地址*/||  
  •           ip_addr_cmp(&(cpcb->local_ip), ipaddr)) /*检验参数IP和已监听pcb列表中IP地址是否相同*/{  
  •         return ERR_USE; //返回端口已被使用信息  
  •       }  
  •     }  
  •   }  
  •   /* Check the connected pcbs. 检查当前连接的pcbs*/  
  •   for(cpcb = tcp_active_pcbs;  
  •       cpcb != NULL; cpcb = cpcb->next) {  
  •     if (cpcb->local_port == port) {  
  •       if (ip_addr_isany(&(cpcb->local_ip)) ||  
  •           ip_addr_isany(ipaddr) ||  
  •           ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {  
  •         return ERR_USE;  
  •       }  
  •     }  
  •   }  
  •   /* Check the bound, not yet connected pcbs.检查已绑定的还没有连接的pcbs */  
  •   for(cpcb = tcp_bound_pcbs; cpcb != NULL; cpcb = cpcb->next) {  
  •     if (cpcb->local_port == port) {  
  •       if (ip_addr_isany(&(cpcb->local_ip)) ||  
  •           ip_addr_isany(ipaddr) ||  
  •           ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {  
  •         return ERR_USE;  
  •       }  
  •     }  
  •   }  
  •   /* @todo: until SO_REUSEADDR is implemented (see task #6995 on savannah),
  •    * we have to check the pcbs in TIME-WAIT state, also: */  
  •   for(cpcb = tcp_tw_pcbs; cpcb != NULL; cpcb = cpcb->next) {  
  •     if (cpcb->local_port == port) {  
  •       if (ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {  
  •         return ERR_USE;  
  •       }  
  •     }  
  •   }  
  •   
  •   if (!ip_addr_isany(ipaddr)) {  
  •     pcb->local_ip = *ipaddr; //IP地址给当前连接的pcb   
  •   }  
  •   pcb->local_port = port;  
  •   TCP_REG(&tcp_bound_pcbs, pcb);    //将当前pcb放入已绑定tcp_pcb列表  
  •   LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"/n", port));  
  •   return ERR_OK;  
  • }  


分析:这个函数的大部分代码用于检验给出的IP地址和端口号是否合适,如果合适则将给出的IP地址和端口号赋给当前PCB,更新已绑定tcp_pcb列表并返回ERR_OK.如果给出的参数不合适,则返回ERR_USE.

参数ipaddr如果为IP_ADDR_ANY,表示绑定到任何本地地址,那么IP_ADDR_ANY是什么呢?在lwip-1.3.0/src/include/ipv4/lwip/ip_addr.h中定义了:

#define IP_ADDR_ANY         ((struct ip_addr *)&ip_addr_any)

ip_addr_any是一个ip_addr型变量,在lwip-1.3.0/src/core/ipv4/ip_addr.c中有如下声明:

                   #define IP_ADDR_ANY_VALUE 0x00000000UL

const struct ip_addr ip_addr_any = { IP_ADDR_ANY_VALUE };

所以, IP_ADDR_ANY是等于0x00000000UL的. 在IP地址上规定  0.0.0.0为广播地址,也就是任意地址的意思.

注1:在tcp.h中有如下定义:

/* The TCP PCB lists. TCP PCB列表*/

union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. 进入监听状态的所有TCP PCB列表*/

  struct tcp_pcb_listen *listen_pcbs;

  struct tcp_pcb *pcbs;

};

extern union tcp_listen_pcbs_t tcp_listen_pcbs;


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

使用特权

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

本版积分规则

146

主题

4098

帖子

5

粉丝