成功移植lwip1.3.1 1.3.2 1.4.1,裸机能跑tcp客户端和服务器。
开心之余,又有些问题需要请教了,lwip里面如何处理断线重连的问题?
下面是我实验的现象:
我在裸机上使用lwip,tcp做了服务器和客户端,在连接后把网线拔掉,tcp_poll函数还是会被执行的,这时候把网线插上(还没出现abort错误),需要重新连接(端口没变,原连接已经没反应了),连接后上一次连接的pcb仍然存在,这时候会发现轮询时候有两个pcb连接在运行。等了好几分钟后(关闭了保活设置)第一个pcb连接出现连接错误,自动断开。。。
这两个pcb占用同一个端口不会产生冲突吗?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
终于回到宿舍了,开始写使用笔记好了。
在写之前,想说明自己比较菜,对tcpip也有很多不懂的地方,还让大虾们高抬贵手。在写笔记前,先附上一些资料和lwip1.4.1的源码。
网速实在太慢了,发不上来,明天到实验室再补全。
宿舍网速太慢了,上传不上去,暂时先传个源码吧
开始正题吧。如果拿到一个可移植的代码,首先关心的就是它给我们留下了什么接口,如何关联我们的底层驱动,如何对它进行裁剪扩充功能等等。
对于比较新手的我们,暂时可以不管lwip的内核是如何操作,只关心我们需要用到的地方。
先看源码的文件目录,可以发现api,core,include和netif四个文件夹。
./api:里面的文件基本是操作系统的应用层接口,鉴于我是裸机下使用和对操作系统一窍不通的尴尬情况,这里就略过好了。
./core:存储了lwip协议栈的重要内容,包括内存的管理,常用协议的内核以及我们需要用到的一些用户接口都在里面了。
./include:对应于.c的相关头文件。
./netif:顾名思义,是net interface,网络接口,这里有我们需要修改的,关联我们的底层驱动。
注:源码内带有sys_XXX字样的文件或者函数大多跟操作系统相关,对操作系统无力的我就直接忽略好了。
lwip不关心我们所使用的平台,所以事先要让lwip知道我们用到的平台信息。如我们用到的编译器支持的字节、半字以及字的定义,MCU数据大小端。
include/arch.h
由arch.h所需的头文件,可以知道存在头文件arch/cc.h。
在cc.h中可以看出,数据长度的关联信息,如图2所示。
这里则需要根据不同的编译器进行适当调整。由cc.h又可以知道有个cpu.h头文件,转入该文件中,发现需要设置大小端BYTE_ORDER,根据实际需要设置就好(图3)。
数据长度格式告知lwip内核之后,可以开始关联底层驱动。
*****************************************************************
lwip只是提供了一个协议栈要做的包的过滤,解包,打包,对于包的内容分析和包的接收与发送是需要我们自己来实现。
之前提到的./netif文件夹,里面有我们关心的文件ethernetif.c,打开它,大概浏览一下,就会发现如果不修改这个文件,是不可能编译过去的,因为,作者各种省略号。。。想编译通过都难。
不过,作者也用心良苦,与底层相关的函数直接用low_level_XXX命名,非常清晰。
static void low_level_init(struct netif *netif)
static err_t low_level_output(struct netif *netif, struct pbuf *p)
static struct pbuf * low_level_input(struct netif *netif)
这三个函数则需要手动修改和添加一些自己的硬件信息和关联驱动。
首先是low_level_init函数,ETHARP_HWADDR_LEN是我们的mac地址长度,6个字节。
紧随其后的是mac地址,
netif->hwaddr[0] = ;
...
netif->hwaddr[5] =;将其补全即可。
题外话:是我们分配给网络芯片的物理地址,如果是局域网,只要不与其他设备地址冲突,是随意设置,但为了测试的可靠性,建议先在cmd窗口使用命令ipconfig /all记下自己电脑的mac地址,我们只对最后8位进行修改即可。如果连接外网,则需要申请一个唯一的mac地址。(不过没申请连外网好像也没发生冲突)。
netif->flags则可以自定义网络芯片的功能,具体可以阅读netif.h头文件,有详细注释,当然,有些功能需要硬件上的支持才可以用,这里相当于一个软件功能开关而已。
说到这里,这个netif变量是什么
这是个struct netif型全局变量,用于记录网络芯片的硬件信息,存储硬件信息也是一个链表,所以lwip支持多网络芯片同时工作,设置默认网络接口,修改网络芯片排序等功能,后面再一一介绍。
唉,写得真慢,要睡了,明天还要出差,明晚再见。
tcpip_callback_with_block 函数。
网线插上:
tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_up, &appNetif, 0);
网线断开:
tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_down, &appNetif, 0);
参数参考相关说明。
一周热门 更多>