LWIP之SOCKET的实现(7)
return netif; } } }
if ((netif_default == NULL) || (!netif_is_up(netif_default))) {
snmp_inc_ipoutnoroutes(); return NULL; }
/* no matching netif found, use default netif */ return netif_default; }
可以说这个函数的实现很简单,且作用也很容易看懂,就像其注释所说的一样。不过在这个函数中我们还是发现了一些什么,对了,就是struct netif *netif_list;【src\\core\\netif.c】的使用。既然这里都使用了这个网络接口链表,那它是在哪里被初始化的呢?
好了,首先我们发现在netif_add函数中有对netif_list的调用,netif_add是被do_netifapi_netif_add函数调用的,而do_netifapi_netif_add是在netifapi_netif_add中通过netifapi_msg被TCPIP_NETIFAPI调用的。问题似乎很清楚,只要找到nnetifapi_netif_add是被谁调用的就好了,然而,搜遍整个工程也没有发现这个函数的影子,除了一个声明一个实现外。My god,又进入死胡同了?好吧,这里先标识一下,待解【见下面的解释】
我们接着看ip_output_if这个函数,具体函数可参考【src\\core\\ipv4\\ip.c】。它的函数定义注释如下:
* Sends an IP packet on a network interface. This function constructs * the IP header and calculates the IP header checksum. If the source * IP address is NULL, the IP address of the outgoing network * interface is filled in as source address.
* If the destination IP address is IP_HDRINCL, p is assumed to already * include an IP header and p->payload points to it instead of the data.
再看最后一句:return netif->output(netif, p, dest);
嗯,看来这个netif还是关键啊,如果估计不错的话,接收的时候也要用到这个结构的。那就看它在什么地方被赋值的吧。又经过一番搜索,看来在目前的代码中是找不到的了。查看lwip协议栈的设计与实现,特别是网络接口层的那一节,终于明白了,原来这些是要有设备驱动来参与的:【一下为引用】
当收到一个信息包时,设备驱动程序调用input指针指向的函数。网络接口通过output指针连接到设备驱动。这个指针指向设备驱动中一个向物理网络发送信息包
的函数,当信息包包被发送时由IP层调用,这个字段由设备驱动的初始设置函数填充。
接下来就是ip层的接收过程了。刚才上面也有提到驱动设备收到包,丢给netif的input函数,这个input函数也是设备驱动层来设置的。无非有两个可能,一个是ip_input,另外一个就是tcpip_input。因为tcpip_input函数的处理是最终调用到了ip_input【在tcpip_thread中】。按照正常情况下应该是ip_input函数的,我们先来看下这个函数。
* This function is called by the network interface device driver when * an IP packet is received. The function does the basic checks of the * IP header such as packet size being at least larger than the header * size etc. If the packet was not destined for us, the packet is * forwarded (using ip_forward). The IP checksum is always checked.
嗯,那就这样吧,到这里我们可以说IP层的发送流程已经走完了。
原型:err_t ip_input(struct pbuf *p, struct netif *inp)
该函数大致的处理过程是:处理ip包头;找到对应的netif;检查如果是广播或多播包,则丢掉;如果是tcp协议的话就直接调用了tcp_input函数处理数据。
到此,ip层的东西大致就说完了。最后,由于tcp和ip层的东西都说完了,所以此时我们顺便看下,tcpip的整体实现,这个主要是在src\\api\\tcpip.c文件中实现。我们知道发送过程是由socket直接调用的,所以这个文件中不涉及,说白了,这个文件主要是涉及到整个接收过程。这里实现的函数有tcpip_input,和tcpip_thread以及tcpip_init函数。
Tcpip_init函数很简单就是创建系统线程(sys_thread_new)tcpip_thread。 Tcpip_thread函数的注释如下:
* The main lwIP thread. This thread has exclusive access to lwIP core functions
* (unless access to them is not locked). Other threads communicate with this
* thread using message boxes.
它的整个过程就是一直从mbox中取出msg,对各种msg的一个处理过程。 Tcpip_input函数,是在tcpip_thread中被调用的处理设备驱动接收到的信息包,并调用
ip_input来进一步处理。
整个启动过程: main---> vlwIPInit() void vlwIPInit( void ) {
/* Initialize lwIP and its interface layer. */ sys_init();
mem_init(); memp_init(); pbuf_init(); netif_init(); ip_init();
sys_set_state(( signed portCHAR * ) \ tcpip_init( NULL, NULL ); sys_set_default_state(); }
从上面我们知道,tcpip_init创建tcpip_thread 在tcpip_thread的开始有如下代码: (void)arg; ip_init();
#if LWIP_UDP udp_init(); #endif
#if LWIP_TCP tcp_init(); #endif
#if IP_REASSEMBLY
sys_timeout(1000, ip_timer, NULL); #endif
if (tcpip_init_done != NULL) {
tcpip_init_done(tcpip_init_done_arg); }
下面是tcp_init的实现 Void tcp_init(void) {
/* Clear globals. */
tcp_listen_pcbs.listen_pcbs = NULL; tcp_active_pcbs = NULL; tcp_tw_pcbs = NULL; tcp_tmp_pcb = NULL; /* initialize timer */ tcp_ticks = 0; tcp_timer = 0; }
LWIP的底层结构(物理层)
我们前面讲到说是ip层的发送和接收都是直接调用了底层,也就是设备驱动层的函数实现,在这里暂且称之为物理层吧。下面就接着ip层的讲,不过由于这里的设备驱动各平台的都不一样,为此,我们选择ARM9_STR91X_IAR这个Demo作为实例,该平台的网络设备驱动在\\library\\source\\91x_enet.c文件中。而ethernetif.c文件就是我们需要的,它是连接设备驱动程序与ip层的桥梁。
Ethernetif.c文件中提供的函数主要有以下这么几个: (1) low_level_init (2) low_level_input (3) low_level_output (4) ethernetif_init (5) ethernetif_input (6) ethernetif_output
这里对外的接口只有ethernetif_init函数,它是main函数中通过
netif_add( &EMAC_if, &xIpAddr, &xNetMast, &xGateway, NULL, ethernetif_init, tcpip_input );来被调用的。我们可以清楚的看到,tcpip_input的使用,它就是被用来当有数据接收的时候被调用的以使接收到的数据进入tcpip协议栈。
在netif_add函数中,我们可以看到 netif->input = input;
if (init(netif) != ERR_OK) {
return NULL; }
Ok,从这里就进入到ethernetif_init函数了,在这个函数中,我们主要看以下几句:
netif->output = ethernetif_output; netif->linkoutput = low_level_output; low_level_init(netif); etharp …… 此处隐藏:3523字,全部文档内容请下载后查看。喜欢就下载吧 ……
相关推荐:
- [实用模板]第八章:法国“新浪潮”与“左岸派”
- [实用模板]2021年北京上半年临床医学检验技师生物
- [实用模板]SAP GUI 7.10客户端安装配置文档
- [实用模板]2001年临床执业医师资格考试综合笔试试
- [实用模板]36机场工作实用英语词汇总结
- [实用模板](一)社会保险稽核通知书
- [实用模板]安全教育主题班会材料
- [实用模板]濉溪县春季呼吸道传染病防控应急演练方
- [实用模板]长沙房地产市场周报(1.30-2.3)
- [实用模板]六年级数学上册典中点 - 图文
- [实用模板]C程序设计(红皮书)习题官方参考答案
- [实用模板]中国证监会第一届创业板发行审核委员会
- [实用模板]桥梁工程复习题
- [实用模板]2011学而思数学及答案
- [实用模板]初中病句修改专项练习
- [实用模板]监理学习知识1 - 图文
- [实用模板]小机灵杯四年级试题
- [实用模板]国贸专业毕业论文模板
- [实用模板]教育学概论考试练习题-判断题4
- [实用模板]2015届高考英语一轮复习精品资料(译林
- 00Nkmhe_市场营销学工商管理_电子商务_
- 事业单位考试法律常识
- 诚信教育实施方案
- 吉大小天鹅食品安全检测箱方案(高中低
- 房地产销售培训资料
- 高一地理必修1复习提纲
- 新概念英语第二册lesson_1_练习题
- 证券公司内部培训资料
- 小学英语时间介词专项练习
- 新世纪英语专业综合教程(第二版)第1册U
- 【新课标】浙教版最新2018年八年级数学
- 工程建设管理纲要
- 外研版 必修一Module 4 A Social Surve
- Adobe认证考试 AE复习资料
- 基于H.264AVC与AVS标准的帧内预测技术
- 《食品检验机构资质认定管理办法》(质
- ABB变频器培训课件
- (完整版)小学说明文阅读练习题及答案
- 深思洛克(SenseLock) 深思IV,深思4,深
- 弟子规全文带拼音




