标签:
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 int
10 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 descriptor
16 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 be
12 * 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的状态是LISTEN
34 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掉旧的pcb
41 #if LWIP_CALLBACK_API
42 lpcb->accept = tcp_accept_null;
43 #endif /* LWIP_CALLBACK_API */
44 #if TCP_LISTEN_BACKLOG
45 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 }
标签:
原文地址:http://www.cnblogs.com/codingfun/p/4186343.html