1.前言

lwIP提供3种应用编程接口来跟TCP/IP内核通信,如下所示:

  • 低水平的内核/回调或raw API
  • 2个高水平序列API:

1) netconn API

2) socket API(为了兼容POSIX/BSD-socket)

2.选择合适的应用编程接口

  • 序列API

序列API提供了一种普通、有序的程序来使用lwIP内核。它与BSD的socket API非常相似。该序列API的模型是建立在阻塞的打开-读-写-关闭(open-read-write-close)模式上。

由于TCP/IP栈本质上是基于事件的,TCP/IP的代码和应用程序必须适应在不同的可执行的上下文(线程)内。

  • RAW API

当原始(raw)和序列API混合使用时,你要很小心了:rawI函数只能被主tcpip_thread调用。注册回调函数(或初始化一个pcb)也一定要在那个上下文中完成(比如,在启动时调用tcpip_init_callback时或运行时调用tcpip_callback)。

  • 选择合适的API的几点建议

1) netconn-和raw-API只属于lwIP本身,用这些API写的代码并不能移植并重新使用在其它协议栈上。

2) socket API与1)相反,用该API写的代码可以付出较小的工作量就可以移植到posix协议栈上。

3) socket-和netconn-API是序列API,该API需要多线程间的支持(一个线程用于使用API,一个线程用来为协议栈处理定时器、接收到的数据包等)

4) RAW API使用回调函数的机制(比如,当新的数据到达时,应用程序的回调函数被调用)。如果你习惯用序列API编程,那么你使用原始API编程会变得比较困难。

5) RAW API由于它不需要线程间的切换可以得到最好的性能。

6) raw-和netconn-API对于发送和接收支持零复制(尽管DMA使能,MACs可以防止对接收的数据进行复制)

3.原始(raw/native)API

3.1 原始API介绍

原始API是一个基于事件驱动的,该API也可以不需要操作系统的支持而且不需要重复复制接收和发送的数据。

内核协议栈经常使用原始API来进行各种协议间的交互。当lwIP没有在操作系统上运行时,只能使用原始API来编程。

应用程序是靠回调函数实现的,当与应用程序相关活动发生时该回调函数被lwIP内核调用。

一个特定的应用可以通过注册基于事件的回调函数被通知,比如刚接收到数据,发送数据,错误通知,查询定时器是否超时,连接关闭,等等。

一个应用可以提供一个回调函数来处理所有的事件。

不要将lwIP的原始API与raw ethernet或IP sockets相混淆。

原始API是lwIP网络协议栈(包括tcp和udp)的一组接口,而原始以太网或IP sockets 则关注处理raw ethernet或IP 数据而不是tcp的连接或udp的数据包。

3.2 与多线程相关的问题

当在一个多线程环境中运行时,由于原始API并没有提供并行访问保护(比如pbuf-和内存管理函数),原始API函数只能被内核线程(tcpip-thread)调用。

由于所有的数据包(输入和输出)和定时器的处理都在同一个可执行上下文中,原始API从不会被阻塞。

3.3 模块

原始API可以访问如下协议:

  • 网络层协议(IPv4/IPv6)
  • 传输层协议:UDP、TCP、RAW IP、ICMP、IGMP
  • 应用层协议:DHCP、AUTOIP、SNMP、DNS(自1.3.0起)
  • 网络接口管理函数
  • 内存和数据包缓存管理函数(相关的内存池和堆栈)
  • 操作系统抽象层

3.4 函数

相关函数的正式描述可以在doc/rawapi.txt找到。如下是一些附加备注:

  • void tcp_accept(struct tcp_pcb *pcb, err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err));

说明:tcp_accept()必须在tcp_listen()后调用,由于:

(1)如果先调用tcp_accept()很可能导致丢失当调用tcp_listen(),原因是tcp_listen()分配一个新的pcb但实际上并没有从老的pcb复制相关的内容(pcb-accept)(请查阅tcp_listen_with_backlog()在lwip/src/core/tcp.c)

(2)所有lwIP原始API都在一个线程中运行,接收到的数据包并不会在tcp_listen()和tcp_accept()之间马上被处理。在pcb被tcp_accept()正确配置前,调用tcp_listen()会导致接受连接而不产生危险。

  • void tcp_setprio(struct tcp_pcb *pcb, u8_t prio);

这个函数并没有被doc/rawapi.txt记录,但是它经常被当例子来使用而没有合适的说明。当内存不够时lwIP将关掉低优先级的tcp连接。这个函数设置了连接的优先级。

  • err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err);

这是一个接收回调函数。该函数可以返回一个错误值。当该函数的返回值与ERR_OK不相同时,数据将被lwIP所缓存。

在下一次调用fasttmr()时,这个数据还会再次发送给应用程序,这样应用程序可以取走该数据或再次拒绝它。

如果有数据等待处理,而又有新的数据包到达,那么该连接将会继续保存应用程序拒绝的数据,该回调函数会被再次调用,并试图发送挂起的数据。

如果应用程序再次拒绝刚接收到的数据那么该数据就会被丢弃。(相关的源文件:tcp.c和tcp_in.c,搜索TCP_EVENT_RECV和refused_data)。

4. Netconn API

4.1 简介

netconn  API是一个序列API,该API被设计来更容易使用lwIP协议栈(与基于事件驱动的原始API相比),而且保留零复制的功能。

4.2 在多线程下的执行

使用netconn API,由于该API要求使用线程,必须需要操作系统的支持。所有的数据包处理(输入和输出)都在一个相关的线程内完成(比如,tcpip-thread)。

使用netconn API的应用线程来通过消息邮箱和信号量和内核线程进行通信

4.3 从应用的角度看netconn API

使用netconn API的应用程序可以使用api.h (netconn_*() functions) and netbuf.h(netbuf_*() functions)中定义的所有函数

netconn API支持的传输层协议包括UDP,TCP和RAW IP

(1)应用可以使用如下函数来跟netconn一起工作

(2)对TCP连接,支持一些额外的功能

  • netconn_listen() - set a TCP connection into listen mode
  • netconn_accept() - accept an incoming connection on a listening TCP connection
  • netconn_write() - send data on a connected TCP netconn
  • netconn_close() - close a TCP netconn without deleting it

(3)为应用程序提供的更高层协议支持

  • netconn_gethostbyname() - Does a name lookup (queries dns server if req'd) to resolve a host name to an IP address
  • netconn_join_leave_group() - basic IGMP multicast support

(4)发送和接收采用netbufs

netbufs具有零复制接收和发送数据的功能。如下函数可以与netbufs一起工作

4.4 Nonblocking IO

从2010年2月的CVS版本,netconn API支持非阻塞的连接

你可以创建自己的回调函数处理netconn_evt事件,如下所示:

- conn = netconn_new_with_callback(NETCONN_TCP, your_callback_function)
- netconn_set_nonblocking(conn, 1)
- netconn_connect(...) -> does not block (as above)

-通过NETCONN_EVT_SENDPLUS (连接) or NETCONN_EVT_ERROR(连接失败)事件等待your_callback_function()函数被调用。

留意线程间的切换:回调函数被tcpip-thread线程调用,并不是在你的应用线程

5. Socket API

5.1 函数

新加入shutdown()(1.3.0)函数并不适合执行。

5.2 外部参考连接

LwIP Application Developers Manual6---Application API layers的更多相关文章

  1. LwIP Application Developers Manual1---介绍

    1.前言 本文主要是对LwIP Application Developers Manual的翻译 2.读者(应用开发手册的读者) 谁适合读这份手册 网络应用的开发者 想了解lwIP的网络应用开发者 阅 ...

  2. LwIP Application Developers Manual2---Protocols概览

    1.前言 本文是对LwIP Application Developers Manual的翻译 lwIP是模块化的并支持广泛的协议,这些大部分协议可以被裁减从而减小代码的尺寸 2.协议概览 链路层和网络 ...

  3. Building Applications with Force.com and VisualForce (DEV401) (二) : Application Essentials:Designing Application on the Force.com Platform

    Dev 401-002:Application Essentials:Designing Application on the Force.com Platform Course Objectives ...

  4. Win32 Console Application、Win32 Application、MFC三者之间的联系和区别

    转自:http://blog.csdn.net/c_base_jin/article/details/52304845 在windows编程中,我们或多或少都听说这三个名称,分别是Win32 Cons ...

  5. Jsoup问题---获取http协议请求失败 org.jsoup.UnsupportedMimeTypeException: Unhandled content type. Must be text/*, application/xml, or application/xhtml+xml.

    Jsoup问题---获取http协议请求失败 1.问题:用Jsoup在获取一些网站的数据时,起初获取很顺利,但是在访问某浪的数据是Jsoup报错,应该是请求头里面的请求类型(ContextType)不 ...

  6. Jsoup获取部分页面数据失败 org.jsoup.UnsupportedMimeTypeException: Unhandled content type. Must be text/*, application/xml, or application/xhtml+xml.

    用Jsoup在获取一些网站的数据时,起初获取很顺利,但是在访问某浪的数据是Jsoup报错,应该是请求头里面的请求类型(ContextType)不符合要求. 请求代码如下: private static ...

  7. application/json和application/x-www-form-urlencoded使用选择

    一.参考资料 选application/x-www-form-urlencoded还是application/json? @RequestBody应用 二.理解 1.@RequestBody的作用 注 ...

  8. SpringBoot application.properties (application.yml)优先级从高到低

    SpringBoot application.properties(application.yml) 优先级从高到低 SpringBoot配置文件优先级从高到低 =================== ...

  9. jdb--gdb---java 远程调试(java application与web application)

    命令比较     gdb              jdb     bt             where     del           clear     stop         brea ...

随机推荐

  1. beego 实现API自动化文档

    安装beego和bee工具 1.beego安装 go get -u github.com/astaxie/beego 2.安装bee工具 go get -u github.com/beego/bee ...

  2. SQL语法基础之DROP语句

    SQL语法基础之DROP语句 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.查看DROP帮助信息 mysql> ? DROP Many help items for yo ...

  3. Python的基础详情

    Python的基础信息 Python是一种动态解释性高级语言 Python即可面向对象,也可以面向过程 解释行语言 无需编译 程序以'行'为单位进行执行 执行速度慢 开发效率快 可跨平台 编译型语言 ...

  4. iptables之NAT端口转发设置

    背景:服务器A:103.110.114.8/192.168.1.8,有外网ip,是IDC的一台服务器服务器B:192.168.1.150,没有外网ip,A服务器是它的宿主机,能相互ping通服务器C: ...

  5. Numpy 笔记: 多维数组的切片(slicing)和索引(indexing)【转】

    目录 切片(slicing)操作 索引(indexing) 操作 最简单的情况 获取多个元素 切片和索引的同异 切片(slicing)操作 Numpy 中多维数组的切片操作与 Python 中 lis ...

  6. setAttribute和setParameter方法的区别

    getAttribute表示从request范围取得设置的属性,必须要先setAttribute设置属性,才能通过getAttribute来取得,设置与取得的为Object对象类型 getParame ...

  7. 服务器部署全程记录(centos6.5)

    1.安装nginx 上传安装包:put E:\yz_index\installPackage\nginx-1.14.0.tar.gz 解压:tar zxvf nginx-1.14.0.tar.gz 切 ...

  8. Django多表操作

    多表创建 创建模型 下面通过一个简单的图书管理系统,来阐述多表的创建和查询操作 在视图函数里里定义如下代码 from django.db import models class Book(models ...

  9. Silverlight用户无法注册之MySql.Data.dll不一致

    本篇博文记录本人解决一个"用户无法注册"的问题的过程 1 问题描述: 用户可以删除:但不能注册,也不能修改权限: 图 1用户注册失败 图 2修改用户权限出错 2 解决过程 1)粗暴 ...

  10. Windows环境手动DOS命令构建apk文件

    第一步 抽取资源id,生成R.java aapt p[ackage] -f [-A <assets>] -S <res> -M <AndroidManifest.xml& ...