




已阅读5页,还剩2页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
LWIP之SOCKET的实现 2009-05-16 00:39:17标签:lwip 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。/214870/158413 2009-05-11 LWIP之SOCKET的实现Lwip协议栈的实现目的,无非是要上层用来实现app的socket编程。好,我们就从socket开始。为了兼容性,lwip的socket应该也是提供标准的socket接口函数,恩,没错,在srcincludelwipsocket.h文件中可以看到下面的宏定义:#if LWIP_COMPAT_SOCKETS#define accept(a,b,c) lwip_accept(a,b,c)#define bind(a,b,c) lwip_bind(a,b,c)#define shutdown(a,b) lwip_shutdown(a,b)#define closesocket(s) lwip_close(s)#define connect(a,b,c) lwip_connect(a,b,c)#define getsockname(a,b,c) lwip_getsockname(a,b,c)#define getpeername(a,b,c) lwip_getpeername(a,b,c)#define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e)#define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e)#define listen(a,b) lwip_listen(a,b)#define recv(a,b,c,d) lwip_recv(a,b,c,d)#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f)#define send(a,b,c,d) lwip_send(a,b,c,d)#define sendto(a,b,c,d,e,f) lwip_sendto(a,b,c,d,e,f)#define socket(a,b,c) lwip_socket(a,b,c)#define select(a,b,c,d,e) lwip_select(a,b,c,d,e)#define ioctlsocket(a,b,c) lwip_ioctl(a,b,c)#if LWIP_POSIX_SOCKETS_IO_NAMES#define read(a,b,c) lwip_read(a,b,c)#define write(a,b,c) lwip_write(a,b,c)#define close(s) lwip_close(s)先不说实际的实现函数,光看这些定义的宏,就是标准socket所必须有的接口。接着看这些实际的函数实现。这些函数实现在srcapisocket.c中。先看下接受连接的函数,这个是tcp的原型:int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)可以看到这里的socket类型参数 s,实际上是个int型在这个函数中的第一个函数调用是sock = get_socket(s);这里的sock变量类型是lwip_socket,定义如下:/* Contains all internal pointers and states used for a socket */struct lwip_socket /* sockets currently are built on netconns, each socket has one netconn */ struct netconn *conn; /* data that was left from the previous read */ struct netbuf *lastdata; /* offset in the data that was left from the previous read */ u16_t lastoffset; /* number of times data was received, set by event_callback(), tested by the receive and select functions */ u16_t rcvevent; /* number of times data was received, set by event_callback(), tested by select */ u16_t sendevent; /* socket flags (currently, only used for O_NONBLOCK) */ u16_t flags; /* last error that occurred on this socket */ int err;好,这个结构先不管它,接着看下get_socket函数的实现【也是在srcapisocket.c文件中】,在这里我们看到这样一条语句sock = &socketss;很明显,返回值也是这个sock,它是根据传进来的序列号在sockets数组中找到对应的元素并返回该元素的地址。好了,那么这个sockets数组是在哪里被赋值了这些元素的呢?进行到这里似乎应该从标准的socket编程的开始,也就是socket函数讲起,那我们就顺便看一下。它对应的实际实现是下面这个函数Int lwip_socket(int domain, int type, int protocol)【srcapisocket.c】这个函数根据不同的协议类型,也就是函数中的type参数,创建了一个netconn结构体的指针,接着就是用这个指针作为参数调用了alloc_socket函数,下面具体看下这个函数的实现static int alloc_socket(struct netconn *newconn) int i; /* Protect socket array */ sys_sem_wait(socksem); /* allocate a new socket identifier */ for (i = 0; i function(&(apimsg-msg); UNLOCK_TCPIP_CORE(); return ERR_OK;* Call the lower part of a netconn_* function* This function is then running in the thread context* of tcpip_thread and has exclusive access to lwIP core code.err_t tcpip_apimsg(struct api_msg *apimsg)【此为非locking的】 struct tcpip_msg msg; if (mbox != SYS_MBOX_NULL) msg.type = TCPIP_MSG_API; msg.msg.apimsg = apimsg; sys_mbox_post(mbox, &msg); sys_arch_sem_wait(apimsg-msg.conn-op_completed, 0); return ERR_OK; return ERR_VAL;其实,功能都是一样的,都是要对apimsg-function函数的调用。只是途径不一样而已。看看它们的功能说明就知道了。这么来说apimsg-function的调用很重要了。从netconn_new_with_proto_and_callback函数的实现,可以知道这个function就是do_newconnVoid do_newconn(struct api_msg_msg *msg) if(msg-conn-pcb.tcp = NULL) pcb_new(msg); /* Else? This new connection already has a PCB allocated. */ /* Is this an error condition? Should it be deleted? */ /* We currently just are happy and return. */ TCPIP_APIMSG_ACK(msg);还是看TCP的,在pcb_new函数中有如下代码:case NETCONN_TCP: msg-conn-pcb.tcp = tcp_new(); if(msg-conn-pcb.tcp = NULL) msg-conn-err = ERR_MEM; break; setup_tcp(msg-conn); break;我们知道在这里建立了这个tcp的连接。至于这个超级牛的函数,以后再做介绍。嗯,还是回过头来接着看accept函数吧。Sock获得了,接着就是newconn = netconn_accept(sock-conn);通过mbox取得新的连接。粗略的估计了一下,这个新的连接应该和listen有关系。那就再次打断一下,看看那个listen操作。lwip_listen - netconn_listen_with_backlog- do_listen- tcp_arg(msg-conn-pcb.tcp, msg-conn);tcp_accept(msg-conn-pcb.tcp, accept_function);/注册了一个接受函数* Accept callback function for TCP netconns.* Allocates a new netconn and posts that to conn-acceptmbox.static err_t accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) struct netconn *newconn; struct netconn *conn; conn = (struct netconn *)arg; /* We have to set the callback here even though * the new socket is unknown. conn-socket is marked as -1. */ newconn = netconn_alloc(conn-type, conn-callback); if (newconn = NULL) return ERR_MEM; newconn-pcb.tcp = newpcb; setup_tcp(newconn); newconn-err = err; /* Register event with callback */ API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); if (sys_mbox_trypost(conn-acceptmbox, newconn) != ERR_OK) /* When returning != ERR_OK, the connection is aborted in tcp_process(), so do nothing here! */ newconn-pcb.tcp = NULL; netconn_f
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 甘肃高考美术培训知识点课件
- 瓷砖胶产品知识培训课件
- 县城郊区果园承包协议8篇
- 集团企业数字化转型、数字驾驶舱、数字化平台方案
- 爱自然课件教学课件
- 诗歌手套课件
- 诗歌写作课件
- 26开国大典课件
- 2025年4月养老护理员题库(含答案)
- 爆米花逃走了课件
- vin码打印管理办法
- 银行反电诈培训课件
- tesol考试的样卷及答案
- 《互联网时代知识产权保护实务和十四五数字经济发展规划解读》学习资料-题库-温州市继续教育-一般公需课
- DB32-T 5156-2025 零碳园区建设指南
- 某大型制造集团“十五五”产业数字化转型规划方案
- 外周血T细胞分离技术详解
- 中医治疗疼痛讲解
- 舞蹈初赛题目及答案
- 机械设计岗位技能考核题库
- 从依恋模式到社交困境:大学生成人依恋与人际问题的深度剖析
评论
0/150
提交评论