LWIP之SOCKET的实现文档格式.docx

上传人:b****4 文档编号:7628555 上传时间:2023-05-08 格式:DOCX 页数:56 大小:54.50KB
下载 相关 举报
LWIP之SOCKET的实现文档格式.docx_第1页
第1页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第2页
第2页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第3页
第3页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第4页
第4页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第5页
第5页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第6页
第6页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第7页
第7页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第8页
第8页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第9页
第9页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第10页
第10页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第11页
第11页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第12页
第12页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第13页
第13页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第14页
第14页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第15页
第15页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第16页
第16页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第17页
第17页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第18页
第18页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第19页
第19页 / 共56页
LWIP之SOCKET的实现文档格式.docx_第20页
第20页 / 共56页
亲,该文档总共56页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

LWIP之SOCKET的实现文档格式.docx

《LWIP之SOCKET的实现文档格式.docx》由会员分享,可在线阅读,更多相关《LWIP之SOCKET的实现文档格式.docx(56页珍藏版)》请在冰点文库上搜索。

LWIP之SOCKET的实现文档格式.docx

这些函数实如今src\api\socket.c中。

先看下承受连接的函数,这个是tcp的

原型:

intlwip_accept(ints,structsockaddr*addr,socklen_t*addrlen)

可以看到这里的socket类型参数s,实际上是个int型

在这个函数中的第一个函数调用是sock=get_socket(s);

这里的sock变量类型是lwip_socket,定义如下:

/**Containsallinternalpointersandstatesusedforasocket*/

structlwip_socket{

/**socketscurrentlyarebuiltonnetconns,eachsockethasonenetconn*/

structnetconn*conn;

/**datathatwasleftfromthepreviousread*/

structnetbuf*lastdata;

/**offsetinthedatathatwasleftfromthepreviousread*/

u16_tlastoffset;

/**numberoftimesdatawasreceived,setbyevent_callback(),

testedbythereceiveandselectfunctions*/

u16_trcvevent;

testedbyselect*/

u16_tsendevent;

/**socketflags(currently,onlyusedforO_NONBLOCK)*/

u16_tflags;

/**lasterrorthatoccurredonthissocket*/

interr;

};

好,这个构造先不管它,接着看下get_socket函数的实现【也是在文件中】,在这里我们看到这样一条语句sock=&

sockets[s];

很明显,返回值也是这个sock,它是根据传进来的序列号在sockets数组中找到对应的元素并返回该元素的地址。

好了,那么这个sockets数组是在哪里被赋值了这些元素的呢?

进展到这里似乎应该从标准的socket编程的开场,也就是socket函数讲起,那我们就顺便看一下。

它对应的实际实现是下面这个函数

Intlwip_socket(intdomain,inttype,intprotocol)

【】

这个函数根据不同的协议类型,也就是函数中的type参数,创立了一个netconn构造体的指针,接着就是用这个指针作为参数调用了alloc_socket函数,下面详细看下这个函数的实现

staticintalloc_socket(structnetconn*newconn)

{

inti;

/*Protectsocketarray*/

sys_sem_wait(socksem);

/*allocateanewsocketidentifier*/

for(i=0;

i<

NUM_SOCKETS;

++i){

if(!

sockets[i].conn){

sockets[i].conn=newconn;

sockets[i].lastdata=NULL;

sockets[i].lastoffset=0;

sockets[i].rcvevent=0;

sockets[i].sendevent=1;

/*TCPsendbufisempty*/

sockets[i].flags=0;

sockets[i].err=0;

sys_sem_signal(socksem);

returni;

}

return-1;

}

对了,就是这个时候对全局变量sockets数组的元素赋值的。

既然都来到这里了,那就顺便看下netconn构造的情况吧。

它的学名叫netconndescriptor

/**Anetconndescriptor*/

structnetconn

/**typeofthenetconn(TCP,UDPorRAW)*/

enumnetconn_typetype;

/**currentstateofthenetconn*/

enumnetconn_statestate;

/**thelwIPinternalprotocolcontrolblock*/

union{

structip_pcb*ip;

structtcp_pcb*tcp;

structudp_pcb*udp;

structraw_pcb*raw;

}pcb;

/**thelasterrorthisnetconnhad*/

err_terr;

/**semthatisusedtosynchroneouslyexecutefunctionsinthecorecontext*/

sys_sem_top_completed;

/**mboxwherereceivedpacketsarestoreduntiltheyarefetched

bythenetconnapplicationthread(cangrowquitebig)*/

sys_mbox_trecvmbox;

/**mboxwherenewconnectionsarestoreduntilprocessed

bytheapplicationthread*/

sys_mbox_tacceptmbox;

/**onlyusedforsocketlayer*/

intsocket;

#ifLWIP_SO_RCVTIMEO

/**timeouttowaitfornewdatatobereceived

(orconnectionstoarriveforlisteningnetconns)*/

intrecv_timeout;

#endif/*LWIP_SO_RCVTIMEO*/

#ifLWIP_SO_RCVBUF

/**maximumamountofbytesqueuedinrecvmbox*/

intrecv_bufsize;

#endif/*LWIP_SO_RCVBUF*/

u16_trecv_avail;

/**TCP:

whendatapassedtonetconn_writedoesn'

tfitintothesendbuffer,

thistemporarilystoresthemessage.*/

structapi_msg_msg*write_msg;

thistemporarilystoreshowmuchisalreadysent.*/

intwrite_offset;

#ifLWIP_TCPIP_CORE_LOCKING

/**TCP:

thistemporarilystoreswhethertowakeuptheoriginalapplicationtask

ifdatacouldn'

tbesentinthefirsttry.*/

u8_twrite_delayed;

#endif/*LWIP_TCPIP_CORE_LOCKING*/

/**Acallbackfunctionthatisinformedabouteventsforthisnetconn*/

netconn_callbackcallback;

到此,对这个构造都有些什么,做了一个大概的理解。

下面以SOCK_STREAM类型为例,看下netconn的new过程:

在lwip_socket函数中有

caseSOCK_DGRAM:

conn=netconn_new_with_callback((protocol==IPPROTO_UDPLITE)?

NETCONN_UDPLITE:

NETCONN_UDP,event_callback);

#definenetconn_new_with_callback(t,c)netconn_new_with_proto_and_callback(t,0,c)

简单实现如下:

structnetconn*

netconn_new_with_proto_and_callback(enumnetconn_typet,u8_tproto,netconn_callbackcallback)

structapi_msgmsg;

conn=netconn_alloc(t,callback);

if(conn!

=NULL)

msg.function=do_newconn;

msg.msg.msg.n.proto=proto;

msg.msg.conn=conn;

TCPIP_APIMSG(&

msg);

returnconn;

主要就看TCPIP_APIMSG了,这个宏有两个定义,一个是LWIP_TCPIP_CORE_LOCKING的,一个非locking的。

分别分析这两个不同类型的函数

*Callthelowerpartofanetconn_*function

*ThisfunctionhasexclusiveaccesstolwIPcorecodebylockingit

*beforethefunctioniscalled.

err_ttcpip_apimsg_lock(structapi_msg*apimsg)

【这个是可以locking的】

LOCK_TCPIP_CORE();

apimsg->

function(&

(apimsg->

msg));

UNLOCK_TCPIP_CORE();

returnERR_OK;

*Thisfunctionisthenrunninginthethreadcontext

*oftcpip_threadandhasexclusiveaccesstolwIPcorecode.

err_ttcpip_apimsg(structapi_msg*apimsg)

【此为非locking的】

structtcpip_msgmsg;

if(mbox!

=SYS_MBOX_NULL){

msg.type=TCPIP_MSG_API;

msg.msg.apimsg=apimsg;

sys_mbox_post(mbox,&

sys_arch_sem_wait(apimsg->

msg.conn->

op_completed,0);

returnERR_VAL;

其实,功能都是一样的,都是要对apimsg->

function函数的调用。

只是途径不一样而已。

看看它们的功能说明就知道了。

这么来说apimsg->

function的调用很重要了。

从netconn_new_with_proto_and_callback函数的实现,可以知道这个function就是do_newconn

Voiddo_newconn(structapi_msg_msg*msg)

if(msg->

conn->

pcb.tcp==NULL){

pcb_new(msg);

/*Else?

This"

new"

connectionalreadyhasaPCBallocated.*/

/*Isthisanerrorcondition?

Shoulditbedeleted?

*/

/*Wecurrentlyjustarehappyandreturn.*/

TCPIP_APIMSG_ACK(msg);

还是看TCP的,在pcb_new函数中有如下代码:

caseNETCONN_TCP:

msg->

pcb.tcp=tcp_new();

err=ERR_MEM;

break;

setup_tcp(msg->

conn);

我们知道在这里建立了这个tcp的连接。

至于这个超级牛的函数,以后再做介绍。

嗯,还是回过头来接着看accept函数吧。

Sock获得了,接着就是newconn=netconn_accept(sock->

通过mbox获得新的连接。

粗略的估计了一下,这个新的连接应该和listen有关系。

那就再次打断一下,看看那个listen操作。

lwip_listen--→netconn_listen_with_backlog--→do_listen--→

tcp_arg(msg->

pcb.tcp,msg->

tcp_accept(msg->

pcb.tcp,accept_function);

//注册了一个承受函数

*AcceptcallbackfunctionforTCPnetconns.

*Allocatesanewnetconnandpoststhattoconn->

acceptmbox.

staticerr_taccept_function(void*arg,structtcp_pcb*newpcb,err_terr)

structnetconn*newconn;

conn=(structnetconn*)arg;

/*Wehavetosetthecallbackhereeventhough

*thenewsocketisunknown.conn->

socketismarkedas-1.*/

newconn=netconn_alloc(conn->

type,conn->

callback);

if(newconn==NULL){

returnERR_MEM;

newconn->

pcb.tcp=newpcb;

setup_tcp(newconn);

err=err;

/*Registereventwithcallback*/

API_EVENT(conn,NETCONN_EVT_RCVPLUS,0);

if(sys_mbox_trypost(conn->

acceptmbox,newconn)!

=ERR_OK)

/*Whenreturning!

=ERR_OK,theconnectionisabortedintcp_process(),

sodonothinghere!

pcb.tcp=NULL;

netconn_free(newconn);

对了,accept函数中从mbox中获取的连接就是这里放进去的。

再回到accept中来,获得了新的连接,接下来就是分配sock了,再然后,再然后?

再然后就等用户来使用接收、发送数据了。

到此整个APP层,也就是传输层以上对socket的封装讲完了。

在最后再总结一些整个途径的调用情况吧

 

LWIP之API_MSG构造及其实现

从上面一篇的socket实现来看,假如要评起到最关键作用的一个构造体,那么structapi_msg当之无愧。

先看下它的定义:

/**Thisstructcontainsafunctiontoexecuteinanotherthreadcontextand

astructapi_msg_msgthatservesasanargumentforthisfunction.

Thisispassedtotcpip_apimsgtoexecutefunctionsintcpip_threadcontext.*/

structapi_msg

/**functiontoexecuteintcpip_threadcontext*/

void(*function)(structapi_msg_msg*msg);

/**argumentsforthisfunction*/

structapi_msg_msgmsg;

功能说的很清楚。

但是详细怎么个操作法还是不知道,没关系,接着看它的调用。

举一个例子,刚好是上一篇中调用,但是没有看详细实现的

err_tnetconn_getaddr(structnetconn*conn,structip_addr*addr,u16_t*port,u8_tlocal)

msg.function=do_getaddr;

r=addr;

msg.msg.msg.ad.port=port;

msg.msg.msg.ad.local=local;

TCPIP_APIMSG(&

returnconn->

err;

说明一下,api_msg构造几乎都是在netconn_xxx函数中被调用,方式千篇一律,除了的赋值不一样外。

上面的调用很简单,对该构造体变量赋值,接着就是调用TCPIP_APIMSG,这个函数上面讲过,可过去看下。

既然如此,就不得不说mbox及其相关函数了。

staticsys_mbox_tmbox=SYS_MBOX_NULL;

再看sys_mbox_t的定义,在【】中

/*Foratotallyminimalandstandalonesystem,weprovidenull

definitionsofthesys_functions.*/

typedefu8_tsys_sem_t;

typedefu8_tsys_mbox_t;

typedefu8_tsys_prot_t;

可以看到这里只是简单的定义成了u8类型,注意上面的红色字体的说明,很明显这个是可移植的一局部,需要根据不同的平台,不同的操作系统详细定义。

可以借鉴焦海波大侠的关于ucos上对lwip的移植笔记来看。

我们可以看到在api_msg构造的处理过程中,所有的信息都是包含在api_msg_msg构造体中的,api_msg只是将其和function简单的组合了。

下面看下

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 节日庆典

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2