1 /** 2 * Set a socket into listen mode. 3 * The socket may not have been used for another connection previously. 4 * 5 * @param s the socket to set to listening mode 6 * @param backlog (ATTENTION: need TCP_LISTEN_BACKLOG=1) 7 * @return 0 on success, non-zero on failure 8 */ 9 int10 lwip_listen(int s, int backlog)11 {12 struct lwip_socket *sock;13 err_t err;14 .............15 sock = get_socket(s); // 根据socket号(面向用户的socket标识)得到lwip内部的socket descriptor16 if (!sock)17 return -1;18 ...............19 err = netconn_listen_with_backlog(sock->conn, backlog); // 接下来看这个函数20 ...............21 return 0;22 }
netconn_listen_with_backlog本身内容很少,主要是向下一连串调用:
1 /** 2 * Set the state of the connection to be LISTEN, which means that it 3 * is able to accept incoming connections. The protocol control block 4 * is reallocated in order to consume less memory. Setting the 5 * connection to LISTEN is an irreversible process. 6 * 7 * @param pcb the original tcp_pcb 8 * @param backlog the incoming connections queue limit 9 * @return tcp_pcb used for listening, consumes less memory.10 *11 * @note The original tcp_pcb is freed. This function therefore has to be12 * called like this:13 * tpcb = tcp_listen(tpcb);14 */15 struct tcp_pcb *16 tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)17 {18 struct tcp_pcb_listen *lpcb;19 20 LWIP_UNUSED_ARG(backlog);21 LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL);22 23 /* already listening? */24 if (pcb->state == LISTEN) {25 return pcb;26 }27 lpcb = memp_malloc(MEMP_TCP_PCB_LISTEN); // 新建了一个pcb,后面会把原来的pcb free掉28 if (lpcb == NULL) {29 return NULL;30 }31 lpcb->callback_arg = pcb->callback_arg; // 新pcb继承旧pcb的一些内容32 lpcb->local_port = pcb->local_port;33 lpcb->state = LISTEN; // 因为用户调用了listen(),所以这个新pcb的状态是LISTEN34 lpcb->so_options = pcb->so_options;35 lpcb->so_options |= SOF_ACCEPTCONN;36 lpcb->ttl = pcb->ttl;37 lpcb->tos = pcb->tos;38 ip_addr_set(&lpcb->local_ip, &pcb->local_ip);39 TCP_RMV(&tcp_bound_pcbs, pcb);40 memp_free(MEMP_TCP_PCB, pcb); // free掉旧的pcb41 #if LWIP_CALLBACK_API42 lpcb->accept = tcp_accept_null;43 #endif /* LWIP_CALLBACK_API */44 #if TCP_LISTEN_BACKLOG45 lpcb->accepts_pending = 0;46 lpcb->backlog = (backlog ? backlog : 1);47 #endif /* TCP_LISTEN_BACKLOG */48 TCP_REG(&tcp_listen_pcbs.listen_pcbs, lpcb); // 把新pcb挂到tcp_listen_pcbs这个链表里49 return (struct tcp_pcb *)lpcb;50 }
联系客服