LWIP -- socket函数分析

一个基本的socket建立顺序是
Server端:socket(), bind(),listen(), accept(), recv(), recvfrom(), recvmsg()
Client端:socket(),connect(), send(), sendto(), sendmsg()

基础知识:LWIP通信邮箱,netconn结构体

本文着重介绍Server端的socket()过程。
用户使用socket时,首先会调用socket()函数创建一个socket。在lwip中实际调用的就是lwip_socket()函数。
Int lwip_socket(int domain, int type, int protocol)
//根据不同类型,创建netconn结构体、pcb、socket,最后将netconn、pcb、socket进行绑定。
流程图:
LWIP -- socket函数分析_第1张图片

1.创建netconn结构体
lwip_socket函数中调用了netconn_new_with_callbacknetconn_new_with_proto_and_callback函数来创建netconn结构体。
其实,netconn_new_with_callback是一个宏,最后还是调用netconn_new_with_proto_and_callback函数来实现。
关于netconn结构体,可以通过索引查看具体结构体成员和接口。
struct netconn* netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback)
//创建一个具有回调函数的新netconn(特定类型),同时也创建了相应的pcb。
netconn_new_with_proto_and_callback函数中,通过netconn_alloc函数创建新的netconn结构体。
struct netconn* netconn_alloc(enum netconn_type t, netconn_callback callback)
//创建一个具有回调函数的新netconn(特定类型)。
netconn_alloc函数中,通过sys_mbox_new函数创建一个LWIP通信邮箱(实质是一个消息队列),将句柄保存在新建的connect结构体中。
err_t  sys_mbox_new (sys_mbox_t *pmbox, INT  size)
//创建一个 lwip 通信邮箱
在LWIP协议栈中,netconn_apimsg函数经常会看到,我们不妨先岔开话题,分析一下netconn_apimsg函数
static err_t  netconn_apimsg(tcpip_callback_fn fn, struct api_msg *apimsg)
//该函数在tcpip_thread的线程上下文中运行,并且具有对lwIP核心代码的独占访问权。
//函数最终会调用参数中的回调函数,并将第二个参数作为回调函数中的参数
//如:fn(apimsg);
2.创建pcb控制块
重新回到netconn_new_with_proto_and_callback函数,新建connect结构体后,通过netconn_apimsg调用回调函数lwip_netconn_do_newconn,创建了新的pcb。
void lwip_netconn_do_newconn(void *m)
//在netconn中创建一个特定类型的新pcb,被netconn_new_with_proto_and_callback函数调用。
lwip_netconn_do_newconn函数中,调用pcb_new函数新建pcb。
static void pcb_new(struct api_msg *msg)
//创建一个特定类型的新pcb,被lwip_netconn_do_newconn函数调用。
至此,lwip_socket函数创建了netconn结构体和pcb控制块,并将它们绑定。
3.创建socket
lwip_socket函数在创建connect结构体后,新建一个pcb控制块与netconn绑定,最后再通过alloc_socket函数创建了socket。
static int alloc_socket(struct netconn *newconn, int accepted)
//为给定的netconn分配一个新的套接字。
alloc_socket函数中,查找sockets[]全局变量(存有系统所有的socket),找出一个未被使用的socket结构体,作为用户调用socket() API申请到的socket结构体,并把它和新建的netconn绑定。
至此,lwip_socket()新建了netconn、pcb和socket,并把这三者绑定在了一条线上。



你可能感兴趣的:(SylixOS,网络)