1@page lwip lwip 2 3[更正文档](https://gitee.com/alios-things/lwip/edit/master/README.md)      [贡献说明](https://help.aliyun.com/document_detail/302301.html) 4 5# 概述 6LwIP(Light Weight Internet Protoco1)是瑞士计算机科学院(Swedish Institute of Computer Science)AdamDunkels等人开发的一套用于嵌入式系统的开放源代码TCP/IP协议栈。LWIP的含义是Light Weight(轻型)IP协议。LWIP可以移植到操作系统上,也可以在无操作系统的情况下独立运行。LWIP TCP/IP实现的重点是在保持TCP协议主要功能的基础上减少对RAM的占用。一般它只需要几十KB的RAM和40 KB左右的ROM就可以运行,这使LWIP协议栈适合在小型嵌入式系统中使用。 7官网:https://savannah.nongnu.org/projects/lwip/ 8将LwIP协议栈分成四层: 91.应用层 102.传输层 113.网络层 124.网卡层 13本文将2,3,4统称为协议层 14应用层支持: 15arp, dhcpd, dns, httpd, ifconfig, iperf, lsfd, mdns, netbiosns, ping, sendfile, snmp, sntp, telnetd, tftp 16 17协议层支持: 18IP (Internet Protocol, IPv4 and IPv6) including packet forwarding over 19 multiple network interfaces 20ICMP (Internet Control Message Protocol) for network maintenance and debugging 21IGMP (Internet Group Management Protocol) for multicast traffic management 22MLD (Multicast listener discovery for IPv6). Aims to be compliant with 23 RFC 2710. No support for MLDv2 24ND (Neighbor discovery and stateless address autoconfiguration for IPv6). 25 Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 26 (Address autoconfiguration) 27UDP (User Datagram Protocol) including experimental UDP-lite extensions 28TCP (Transmission Control Protocol) with congestion control, RTT estimation 29 and fast recovery/fast retransmit 30raw/native API for enhanced performance 31Optional Berkeley-like socket API 32DNS (Domain names resolver) 33 34## 版权信息 35> Apache license v2.0 36 37## 目录结构 38```tree 39├── api 40│ ├── api_lib.c # 库 41│ ├── api_msg.c # 消息机制 42│ ├── err.c # 异常api 43│ ├── netbuf.c # 网络缓存api 44│ ├── netdb.c # dns实现 45│ ├── netifapi.c # 网卡api 46│ ├── sockets.c # 套接字api 47│ └── tcpip.c # tcpip任务实现 48├── apps # LwIP 应用 49│ ├── arp # arp应用 50│ ├── dhcpd # dhcpd应用 51│ ├── dns # dns应用 52│ ├── httpd # httpd应用 53│ ├── ifconfig # ifconfig应用 54│ ├── iperf # iperf应用 55│ ├── lsfd # lsfd应用 56│ ├── mdns # mdns应用 57│ ├── netbiosns # netbiosns应用 58│ ├── ping # ping应用 59│ ├── sendfile # sendfile应用 60│ ├── snmp # snmp应用 61│ ├── sntp # sntp应用 62│ ├── telnetd # telnetd应用 63│ └── tftp # tftp应用 64├── core # LwIP协议栈核心模块,IPv4/IPv6/TCP/UDP等协议实现 65├── include # 头文件 66├── netif # 网卡锡相关 67└── port # 移植对接 68``` 69 70## 依赖组件 71 72# 常用配置 73系统中相关配置已有默认值,如需修改配置,统一在yaml中**def_config**节点修改,具体如下: 74> 使能TCPIP是1,不使能TCPIP是0,默认是1,可修改yaml配置如 75```yaml 76def_config: 77 CONFIG_TCPIP: 1 78``` 79> 使用AOS的LwIP是1, 不实用AOS的LwIP是0,默认是1,可修改yaml配置如: 80```yaml 81def_config: 82 CONFIG_AOS_LWIP: 1 83``` 84> 使能LwIP数据包打印功能是1, 不使能是0,默认1,可修改yaml配置如: 85```yaml 86def_config: 87 WITH_LWIP_PKTPRINT: 1 88``` 89 90# API说明 91 92## 创建socket 93```C 94int socket(int domain, int type, int protocol); 95``` 96 97|args |description| 98|:----- |:----| 99|domain |协议域| 100|type |类型| 101|protocol |传输协议| 102 103## 绑定地址端口 104```C 105int bind(int s, const struct sockaddr *addr, socklen_t namelen) 106``` 107 108|args |description| 109|:----- |:----| 110|s |要绑定的 socket描述符| 111|addr |一个指向含有本机 IP 地址和端口号等信息的 sockaddr 结构的指针| 112|namelen |sockaddr 结构的长度| 113 114## 将套接字设为监听模式,并在套接字指定的端口上开始监听,以便对到达的服务请求进行处理 115```C 116int listen(int s, int backlog) 117``` 118 119|args |description| 120|:----- |:----| 121|s |要绑定的 socket描述符| 122|backlog |连接请求队列可以容纳的最大数目| 123 124## 从完全建立的连接的队列中接受一个连接 125```C 126int accept(int s, struct sockaddr *addr, socklen_t *addrlen) 127``` 128 129|args |description| 130|:----- |:----| 131|s |socket描述符| 132|backlog |连接请求队列可以容纳的最大数目| 133 134## 与服务器建立一个 TCP 连接 135```C 136int connect(int s, const struct sockaddr *name, socklen_t namelen) 137``` 138 139|args |description| 140|:----- |:----| 141|s |socket描述符| 142|name |指向 sockaddr 结构的指针,存放要连接的服务器的 IP 地址和端口号等信息| 143|namelen |sockaddr 结构体的长度| 144 145## 面向连接的数据流 socket 模式下发送数据 146```C 147int send(int s, const void *dataptr, size_t size, int flags) 148``` 149 150|args |description| 151|:----- |:----| 152|s |socket描述符| 153|dataptr |指向所要发送的数据区的指针| 154|size |要发送的字节数| 155|flags |控制选项,通常为 0| 156 157## 面向连接的数据流 socket 模式下接收数据 158```C 159int recv(int s, void *mem, size_t len, int flags) 160``` 161 162|args |description| 163|:----- |:----| 164|s |socket描述符| 165|mem |指向存储数据的内存缓存区的指针| 166|len |缓冲区的长度| 167|flags |控制选项,通常为 0| 168 169## 在无连接的数据报 socket 模式下发送数据 170```C 171int sendto(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen) 172``` 173 174|args |description| 175|:----- |:----| 176|s |socket描述符| 177|size |要发送的字节数| 178|flags |控制选项,通常为 0| 179|to |指向 sockaddr 结构体的指针,存放目的主机的 IP 和端口号| 180|tolen |sockaddr 结构体的长度| 181 182## 在无连接的数据报 socket 模式下接收数据 183```C 184int recvfrom(int s, void*mem, size_t size, int flags, struct sockaddr *from, socklen_t *fromlen) 185``` 186 187|args |description| 188|:----- |:----| 189|s |socket描述符| 190|mem |指向存储数据的内存缓存区的指针| 191|size |缓冲区的长度| 192|flags |控制选项,通常为 0| 193|from |指向 sockaddr 结构体的指针,存放源主机的 IP 和端口号| 194|fromlen |指向 sockaddr 结构体的长度的指针| 195 196## 查询一个或者多个socket的可读性、可写性及错误状态信息 197```C 198int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, 199 struct timeval *timeout) 200``` 201 202|args |description| 203|:----- |:----| 204|maxfdp1 |最大的文件描述符| 205|readset |读文件描述符| 206|writeset |写文件描述符| 207|exceptset |异常的文件描述符| 208|timeout |超时时间| 209 210## 传输完数据之后关闭 socket 并释放资源 211```C 212int closesocket(int s) 213``` 214 215|args |description| 216|:----- |:----| 217|s |socket 描述符| 218 219## 允许进行单向的关闭操作,或是全部禁止掉 220```C 221int shutdown(int s, int how) 222``` 223 224|args |description| 225|:----- |:----| 226|s |socket 描述符| 227|how |控制选项| 228 229## 通过域名来获取主机的 IP 地址等信息 230```C 231struct hostent* gethostbyname(const char*name) 232``` 233 234|args |description| 235|:----- |:----| 236|name |主机域名| 237 238## 获取本地主机的信息 239```C 240int getsockname(int s, struct sockaddr *name, socklen_t *namelen) 241``` 242 243|args |description| 244|:----- |:----| 245|s |socket 描述符| 246|name |sockaddr 结构体指针,用来存储得到的主机信息| 247|namelen |指向 sockaddr 结构体的长度的指针| 248 249## 得到与本地主机连接的远程主机的信息 250```C 251int getpeername(int s, struct sockaddr *name, socklen_t *namelen) 252``` 253 254|args |description| 255|:----- |:----| 256|s |socket 描述符| 257|name |sockaddr 结构体指针,用来存储得到的主机信息| 258|namelen |指向 sockaddr 结构体的长度的指针| 259 260## 设置套接字控制模式 261```C 262int ioctlsocket(int s, long cmd, void *argp) 263``` 264 265|args |description| 266|:----- |:----| 267|s |socket 描述符| 268|cmd |套接字操作命令| 269|argp |操作命令所带参数| 270 271## 获取套接字控制模式 272```C 273int getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen) 274``` 275 276|args |description| 277|:----- |:----| 278|s |socket 描述符| 279|level |选项定义的层次;目前支持SOL_SOCKET, SOL_PACKET, IPPROTO_IP和IPPROTO_TCP| 280|optname |需设置的选项| 281|optval |指向option属性的指针| 282|optlen |指向option属性长度的指针| 283 284## 设置套接字控制模式 285```C 286int setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen) 287``` 288 289|args |description| 290|:----- |:----| 291|s |socket 描述符| 292|level |选项定义的层次;目前支持SOL_SOCKET, SOL_PACKET, IPPROTO_IP和IPPROTO_TCP| 293|optname |需设置的选项| 294|optval |指向option属性的指针| 295|optlen |option属性的长度| 296 297# 使用示例 298 299组件使用示例相关的代码下载、编译和固件烧录均依赖AliOS Things配套的开发工具,所以首先需要参考[《AliOS Things集成开发环境使用说明之搭建开发环境》](https://help.aliyun.com/document_detail/302378.html),下载安装。 300待开发环境搭建完成后,可以按照以下步骤进行示例的测试。 301 302## 步骤1 创建或打开工程 303 304**打开已有工程** 305 306如果用于测试的案例工程已存在,可参考[《AliOS Things集成开发环境使用说明之打开工程》](https://help.aliyun.com/document_detail/302381.html)打开已有工程。 307 308**创建新的工程** 309 310组件的示例代码可以通过编译链接到AliOS Things的任意案例(solution)来运行,这里选择helloworld_demo案例。helloworld_demo案例相关的源代码下载可参考[《AliOS Things集成开发环境使用说明之创建工程》](https://help.aliyun.com/document_detail/302379.html)。 311 312## 步骤2 添加组件 313 314案例下载完成后,需要在helloworld_demo组件的package.yaml中添加对组件的依赖: 315 316```yaml 317depends: 318 - netmgr:master # 添加netmgr依赖,使用netmgr连接wifi 319 - lwip:master # helloworld_demo中引入lwip组件 320``` 321 322## 步骤3 下载组件 323 324在已安装了 的开发环境工具栏中,选择Terminal -> New Terminal启动终端,并且默认工作路径为当前工程的workspace,此时在终端命令行中输入: 325 326```shell 327 328aos install lwip 329 330``` 331 332上述命令执行成功后,组件源码则被下载到了./components/lwip路径中。 333 334## 步骤4 添加示例 335 336在lwip组件的package.yaml中添加[example示例代码](https://gitee.com/alios-things/lwip/tree/master/example): 337 338```yaml 339source_file: 340 - example/*.c 341``` 342## 步骤5 编译固件 343 344在示例代码已经添加至组件的配置文件,并且helloworld_demo已添加了对该组件的依赖后,就可以编译helloworld_demo案例来生成固件了,具体编译方法可参考[《AliOS Things集成开发环境使用说明之编译固件》](https://help.aliyun.com/document_detail/302384.html)。 345 346## 步骤6 烧录固件 347 348helloworld_demo案例的固件生成后,可参考[《AliOS Things集成开发环境使用说明之烧录固件》](https://help.aliyun.com/document_detail/302383.html)来烧录固件。 349 350## 步骤7 打开串口 351 352固件烧录完成后,可以通过串口查看示例的运行结果,打开串口的具体方法可参考[《AliOS Things集成开发环境使用说明之查看日志》](https://help.aliyun.com/document_detail/302382.html)。 353 354当串口终端打开成功后,可在串口中输入help来查看已添加的测试命令。 355 356## 步骤8 测试示例 357 358> CLI命令行输入netmgr相关命令进行联网操作: 359```sh 360netmgr_example # 启动netmgr组件 361netmgr -t wifi -c wifissid wifipassword # 输入ssid和密码 362``` 363> CLI命令行输入udp 测试命令: 364```sh 365test_udp 366``` 367**关键日志** 368> 输入联网命令后的WIFI联网成功日志: 369```sh 370Got IP 371``` 372> 启动test_udp之后的数据接收打印: 373```sh 374test_udp 375 376(cli-uart)# hello world! count 15 377recv: hello UDP 378hello world! count 16 379recv: hello UDP 380hello world! count 17 381recv: hello UDP 382hello world! count 18 383recv: hello UDP 384hello world! count 19 385recv: hello UDP 386``` 387# 注意事项 388* 使用lwip前,请先确定已经联网 389 390# 测试示例 391> CLI命令行输入ping测试命令 392```sh 393ping -c count(发包的数量) -i interval(发包的时间间隔ms) -s packetsize(指定发包的字节数) -w timeout(指定超时时间ms) destination(指定目标地址) 394``` 395> CLI命令行输入查看设备网络接口的配置信息命令 396```sh 397ifconfig 398``` 399> CLI命令行输入tftp向服务器获取文件命令 400```sh 401tftp server <start|stop> 402tftp get server_ip(服务器ip) server_port(服务器端口) server_src_path(服务器文件路径) device_dest_path(设备目标文件路径) file_type(文件类型) 403示例:tftp get 192.168.0.101 69 1.txt /data/1.txt text 404``` 405> CLI命令行输入iperf测试网络性能 406```sh 407Iperf TCP Server: iperf -s 408Iperf UDP Server: iperf -s -u 409Iperf TCP Client: iperf -c ip(服务器ip地址) -w window size(TCP窗口大小) -t duration(传输时间,默认10s) -p port(服务器端口号) 410示例:iperf -c 192.168.0.101 -w 65535 -t 10 -p 5001 411Iperf UDP Client: iperf -c ip(目标ip地址) -u -l datagram size(数据包大小) -t duration(传输时间,默认10s) -p port(服务器端口号) 412示例:iperf -c 192.168.0.101 -u -l 1500 -t 10 -p 5001 413``` 414**关键日志** 415> ping成功收到数据包日志 416```sh 417 LwIP_recv 418``` 419> ifconfig成功查看设备网络接口的配置信息日志 420```sh 421 en1 up, address:192.168.0.102 gateway:192.168.0.1 netmask:255.255.255.0 422 lo0 up, address:127.0.0.1 gateway:127.0.0.1 netmask:255.0.0.0 423``` 424> tftp成功获取文件日志 425```sh 426tftp received len:92 done 427``` 428> iperf测试日志 429```sh 430TCP Server Bandwidth: 8 Mbits 716 Kbits 848 bits/sec 431UDP Server Bandwidth: 10 Mbits 60 Kbits 344 bits/sec 432TCP Client Bandwidth: 5 Mbits 1023 Kbits 928 bits/sec 433UDP Client Bandwidth: 22 Mbits 907 Kbits 160 bits/sec 434``` 435# FAQ 436NA 437