lwIP(V1.3.0) RAW API函数源码分析2----tcp_bind()函数
2011-02-16 16:21
435 查看
位于: 位于:lwip-x.x.x/src/core/tcp.c
原型: err_t tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
功能:绑定连接到一个本地端口号和IP地址.
函数源码:
分析:这个函数的大部分代码用于检验给出的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;
原型: err_t tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
功能:绑定连接到一个本地端口号和IP地址.
函数源码:
/** * 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;
相关文章推荐
- lwIP(V1.3.0) RAW API函数源码分析1----tcp_new()函数
- lwIP(V1.3.0) RAW API函数源码分析3----tcp_listen()函数
- lwIP(V1.3.0) RAW API函数源码分析4----tcp_accept()函数
- lwIP(V1.0.0) RAW API函数源码分析2----tcp_bind()函数
- lwIP(V1.0.0) RAW API函数源码分析3----tcp_listen()函数
- lwIP(V1.0.0) RAW API函数源码分析4----tcp_accept()函数
- LwIP(V1.0.0) RAW API函数源码分析1----tcp_new()函数
- 如何在tcp源码中分析丢包,加入自己的函数
- lwip源码分析6——tcp层
- TCP/IP源码学习(58)——inet_select_addr函数分析
- LwIP tcp/ip socket编程listen函数分析
- [LWIP学习]--bind函数分析
- LwIP tcp/ip socket编程listen函数分析
- 从Spark-Shell到SparkContext的函数调用路径过程分析(源码)
- Linux TCP/IP 协议栈源码分析
- CI框架源码解读之URI.php中_fetch_uri_string()函数用法分析
- 【Netty源码分析】Netty服务端bind端口过程
- Linux TCP/IP 协议栈源码分析 - 数据 发送/接收 流程图
- HashMap源码之hash()函数分析(JDK 1.8)
- 几种开放源码的TCPIP协议栈概述--LwIP,uIP,TinyTcp和uC/IP