a basic socket establishment sequence isServer side:
- Socket ()
- Bind ()
- Listen ()
- Accept ()
- Recv ()
Client side:
- Socket ()
- Connect ()
- Send ()
This article focuses on the server-side Listen () process. when the user calls listen () using the socket, the actual call is Lwip_listen () in lwIP. The code is as follows
1 /**2 * Set A socket into listen mode.3 * The socket may not be been used for another connection previously.4 *5 * @param s the socket to set to listening mode6 * @param backlog (attention:need tcp_listen_backlog=1)7 * @return 0 on success, Non-zero on Failure8 */9 intTenLwip_listen (intSintbacklog) One { A structLwip_socket *sock; - err_t err; - ............. theSock = Get_socket (s);//gets the socket inside the LWIP based on the socket number (the user-facing socket ID) Descriptor - if(!sock) - return-1; - ............... +Err = Netconn_listen_with_backlog (sock->conn, backlog);//next look at this function - ............... + return 0; A}
The netconn_listen_with_backlog itself is very small, mostly down a series of calls:
Netconn_listen_with_backlog=>do_listen=>tcp_listen=>tcp_listen_with_backlog Tcp_listen_with_backlog This function is really the place to do important work.
1 /**2 * Set The state of the connection to being LISTEN, which means that it3 * is able to accept incoming connections. The Protocol control block4 * is reallocated on order to consume less memory. Setting the5 * Connection to LISTEN are an irreversible process.6 *7 * @param PCB the original TCP_PCB8 * @param backlog the Incoming Connections queue limit9 * @return TCP_PCB used for listening, consumes less memory.Ten * One * @note The original TCP_PCB is freed. This function therefore have to be A * Called like this: - * TPCB = Tcp_listen (TPCB); - */ the structTCP_PCB * -Tcp_listen_with_backlog (structTCP_PCB *PCB, u8_t backlog) - { - structTcp_pcb_listen *LPCB; + - Lwip_unused_arg (backlog); +Lwip_error ("TCP_LISTEN:PCB already connected", pcb->state = = CLOSED,returnNULL); A at /*already listening?*/ - if(Pcb->state = =LISTEN) { - returnPCB; - } -LPCB = Memp_malloc (Memp_tcp_pcb_listen);//Create a new PCB, the back will be the original PCB free off - if(LPCB = =NULL) { in returnNULL; - } toLpcb->callback_arg = pcb->callback_arg;//new PCB inherit some content of old PCB +Lpcb->local_port = pcb->Local_port; -Lpcb->state = LISTEN;//because the user called Listen (), the status of this new PCB is listen theLpcb->so_options = pcb->so_options; *Lpcb->so_options |=Sof_acceptconn; $Lpcb->ttl = pcb->ttl;Panax NotoginsengLpcb->tos = pcb->tos; -Ip_addr_set (&LPCB->LOCAL_IP, &pcb->local_ip); theTCP_RMV (&Tcp_bound_pcbs, PCB); +Memp_free (MEMP_TCP_PCB, PCB);//Free off the old PCB A #ifLwip_callback_api theLpcb->accept =Tcp_accept_null; + #endif/* LWIP_CALLBACK_API */ - #ifTcp_listen_backlog $Lpcb->accepts_pending =0; $Lpcb->backlog = (Backlog:1); - #endif/* Tcp_listen_backlog */ -Tcp_reg (&tcp_listen_pcbs.listen_pcbs, LPCB);//hook up the new PCB to the Tcp_listen_pcbs list . the return(structTCP_PCB *) LPCB; -}
Note the comments above the reading function, which briefly describe the functions of the function and are useful for writing. Tcp_listen_with_backlog This function is to re-open a PCB instead of the old PCB (for space-saving considerations), the status of the new PCB is set to listen, and hang it in the lwIP tcp_listen_ PCBs this list.
lwIP Socket Quest Listen