LWIP协议栈的分析和设计

上传人:s****a 文档编号:120777892 上传时间:2022-07-18 格式:DOCX 页数:13 大小:289.66KB
返回 下载 相关 举报
LWIP协议栈的分析和设计_第1页
第1页 / 共13页
LWIP协议栈的分析和设计_第2页
第2页 / 共13页
LWIP协议栈的分析和设计_第3页
第3页 / 共13页
点击查看更多>>
资源描述
计算机网络与控制LWIP协议栈的分析摘 要近些年来,随着互联网和通讯技术的迅猛发展,除了计算机之外,大量的嵌入式设 备也需求接入网络。目前,互联网中使用的通讯协议基本是TCP/IP协议族,可运行于不 同的网络上,本文研究的就是嵌入式TCP/IP协议栈LWIP。文章首先分析了 LWIP的整体 结构和协议栈的实现,再介绍协议栈的内存管理,最后讲解协议栈应用程序接口。关键词:嵌入式系统;协议;LWIP;以太网AbstractWith the rapid development of internet and communication technology, Not only computers but also embeded equipments are need to connect networks. At present, the basic communication protocol using in internet is TCP/IP, it can run in different network. This paper analyses the Light-Weight TCP/IP. The process model of a protocol implementation and processing of every layer are described first, and then gives the detailed management of Buffer and memory. At last, a reference lwIP API is given.Key words: Embedded System, Protocol, Light weight TCP/IP, Ethernet引言近期互联网络硬件、软件的迅猛发展,使得网络用户呈指数增长,在使用计算机进行网络互联 的同时,各种家电设备、仪器仪表以及工业生产中的数据采集与控制设备在逐步地走向网络化,以 便共享网络中庞大的信息资源。在电子设备日趋网络化的背景下,引人TCP/IP协议栈,以支持嵌 人式设备接人网络,成为嵌人式领域重要的研究方向。本文分析一个轻量级的嵌入式系统的TCP/IP 协议栈-LWIP,LWIP是一个比较完整和可靠的TCP/IP协议栈,具有开源,易用,系统资源要求不高 等优点。一、LWIP概览LWIP是瑞典计算机科学院(Swedish Institute of Computer Science)开发的一套用于嵌入式 系统的开放源代码TCP/IP协议栈。LWIP的含义是Light Weight(轻型)IP协议。LWIP TCP/IP实 现的重点是在保持TCP协议主要功能的基础上减少处理和内存需求,因为LWIP使用无顺数据复制并 经裁剪的API,一般它只需要几十KB的RAM和40KB左右的ROM就可以运行。同时LWIP可以移植到 操作系统上,也可以在无操作系统的情况下独立运行。这使LWIP协议栈适合在低端嵌入式系统中使 用。LWIP的特性如下:1. 支持多网络接口下的IP转发;2. 支持ICMP协议;3. 支持主机和路由器进行多播的Internet组管理协议(IGMP);4. 包括实验性扩展的UDP(用户数据 报协议);5. 包括阻塞控制,RTT估算和快速恢复和快速转发的TCP;6. 提供专门的内部回调接口(raw API)用;7. 支持DNS;8. 支持 SNMP;9. 支持PPP;10. 支持 ARP;11. IP fragment 的支持;12. 支持DHCP协议,动态分配IP地址;13. 可选择的Berkeley接口 API (多线程情况下);LWIP的源代码从作者Adam Dunkels的官方网站上下载(网址为:www.sics.se/adam/lwip/), 版本号为1.3.1。以下为解压后的目录结构。LWIP的目录结构主要分为五个部分:1. Api :应用程序接口文件,包括RAW,BSD以及正式提供的3种API。2. Arch :与硬件和OS有关的文件,包括网络驱动,移植需要修改的文件。3. Core:ICMP,IP,TCP,UDP协议的实现文件,以及一些辅助函数,LWIP实现的核心代码。4. Include :LWIP 的包括文件。5. Netif :ARP协议和LWIP网络设备驱动程序的模板,用户为自己的网络接口设计的驱动 程序应该与ethernetif.c中给出的驱动框架相同。二、LwIP的整体构架和进程模型:传统的TCP/IP协议栈的实现方法严格分层,一般每一层都是一个独立的进程。这样方法虽然有利于协议栈的调试,但是,其最大的弊端为数据包跨层传递时会引起频繁的上下文的切换,尤其 是在多任务系统中,这样导致时间的浪费而直接影响到系统的实时性。LWIP将所有TCP/IP协议都 放在在一个进程当中,这样TCP/IP协议栈就和操作系统内核分开了。而应用层程序既可以是单独 的进程也可以驻留在TCP/IP进程中。如果应用程序是单独的进程,可以通过操作系统的邮箱、消 息队列等通讯机制和TCP/IP进程进行通讯。如果应用层程序驻留在TCP/IP程中,那应用层程序就利用内部回调函数接口(Raw API)和TCP/IP协议栈通讯。LWIP进程模式的主要优点是可以很方“tcpip_thread”任务中,而位于图中最上方的Application layer”(应用层)和下方的“Network interface layer”(网络接口驱动层)由用户自己来实现。应用层程序既可以是独立的任务(如图中 正上方的“tftp_thread”和“tcpecho_thread”),通过mbox(消息队列)和LWIP进程通讯;也可 以在“tcpip_thread”(如图左上角)中利用原始接口(Raw API)和TCP/IP协议栈通讯。LWIP的数据流程主要分为接收和发送两种情况。接收数据时:数据包从一个网络接口被接收,如果网络接口驱动通过low_level_input函数读到 这个数据包,简单的区分是ARP包还是IP包。如果是ARP包,将调用ARP的功能处理这个包。通常 将更新一个ARP地址映射表,然后将数据包发送给IP_input函数处理。如是查一个IP包,将把数 据包发送给ip_input函数处理。IP_input函数将数据包进行简单的处理(如计算校验和)后,分析 该包是发送到本机的正常数据包,IP_input则根据包的类型,分别发送给udp_input、tcp_input、 icmp_input函数处理。如果是发送给UDP或TCP协议的数据包,UDP、TCP协议的处理函数将做相应的处理,最后发送给应用程序。发送数据流程:当应用程序需要发送一个数据包的时候,它将调用UDP和TCP协议处理函数 udp_sender或tcp_write函数发送该数据包。UDP和TCP协议的处理函数接收数据后,将数据打包、 分段,然后发送给IP层ip_output_if函数(需要时,将调用ip_route函数进行路由选择),该函 数把数据打包、封装,然后调用网络接口驱动的low_level_output函数传给网络接口。三、LWIP协议栈的实现3.1网络接口LwIP使用一个与BSD中相似的网络接口结构来表示底层网络驱动,结构体的原型定义如下所示。struct netif struct netif *next;char name2;int num;struct ip_addr ip_addr;struct ip_addr netmask;struct ip_addr gw;void (* input)(struct pbuf *p, struct netif *inp);int (* output)(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr);void *state;next指针用于将网络接口链入到全局链表中。Name域用于表示网络接口的类型,只用于这个接 口在运行时由人工操作进行配置。Name由设备驱动设置并且应该反映硬件的种类。num用来区分相 同类别的不同网络接口。三个IP地址ip_addr,netmask与gw分别用来表示IP地址,子网掩码, 网关。State表示设备驱动所包含的网络接口状态,由设备驱动设置。当设备驱动接受到一个信息包的时候需要调用input指向的函数。而网络接口通过output指针与 设备驱动连接。这个指针指向处于设备驱动中的发送信息包的函数,这个函数将在一个信息包发送 出去后,被IP层调用。指针output将在设备驱动初始化的时候赋值。3.2 IP处理LwIP仅实现了 IP层大部分的基本功能,能够发送、接收以及转发信息包,但是不能接收和发 送IP分片包,也不能处理携带IP参数选项的信息包。不过对大多数的应用来说,这不会引起任何 问题。接收信息包收到的IP信息包,由网络设备驱动调用ip_input()函数开始处理。在这里完成对IP版本字段 及包头长度的初始完整性检查,同时还要计算和验证包头校验和。协议栈假定代理会重新组合IP分 片包为一个完整的包。接下来,函数检查目的地址是否与网络接口的IP地址相符以确定信息包是否 到达预定主机。网络接口在链表中被排序并且采用了线性检索。如果一个到达的信息包被发现已经 到达了目的主机,则由协议字段来决定信息包应该传送到哪一个上层协议。发送信息包外发的信息包由ip_output()函数处理,该函数使用ip_route()函数查找适当的网络接口来传 送信息包。当外发的网络接口确定后,信息包传给以外发网络接口为参数的ip_output_if()函数。-5 -在这里,所有的IP包头字段被填充,并且计算IP包头校验和IP信息包的源及目标地址作为参数 被传递给ip_output_if ()函数。转发信息包如果没有网络接口的地址与到达的信息包的目标地址相同,信息包应该被转发。这项工作由 ip_forward()函数完成。在这里,TTL字段值被减少(Time To Live的简写,生存时间的意思,译 者注),当减为0的时候,将会给IP信息包的最初发送者发送ICMP错误信息,并抛弃该信息包。 最后,信息包被转发到适当的网络接口。查找适当的网络接口的算法与发送信息包使用的算法相同。 ICMP处理网际控制报文协议ICMP(Intemet Control Message Protoc01)总是与IP协议配置在一起,它 运行在IP协议之上,发送一些控制信息,帮助Intemet处理差错。ICMP处理是相当简单的。由ip _input()收到的ICMP包被移交到icmpinput(),它解析ICMP报头并且进行适当的处理。ICMP处 理过程如图3-1所示7i,心zspoE: layer图3 - 1 ICMP处理3.3 UDP处理用户数据报协议UDP(User Datagram Protoc01)较为简单,输出处理也较简单,基本的UDP处 理过程被分割为三个功能函数来实现:如图3-2所示。 udp_input ()函数与UDP输入有关 udp_send()及 udp_output()则用于 UDP 输出图3 - 2 UDP处理3.4 TCP处理传输层控制协议TCP为应用层提供可靠的二进制数据流服务。TCP协议比这里描述的其它协议都要复杂,基本TCP处理如图3-3所示,被划分成六个函数:函数tcp_input()、tcp_process()、 tep_receive()与 TCP 输入处理有关;tep_write()、top_enqueue()、tcp_output ()对输出进行处理。当应用程序想要发送TCP数据时,函数tcp_write()将被调用,函数tcp_write()将控制权交给 tcp_enqueue(),该函数将数据分成合适大小的TCP段(如果必要),并放进发送队列。接下来函数 top_output()将检查数据是否可以发送。也就是说,如果接收器的窗口有足够的空间并且拥塞窗口 足够大,则使用ip_route()和ip_output_if ()两个函数发送数据。当ip_input ()对IP报头进行检验且把TCP段移交给tcp_input()函数后,输入处理开始。在该 函数中将进行初始检验(也就是checksumming和TCP剖析)并决定该段属于哪个TCP连接。该段于是 由tcp_process()处理,它实现TCP状态机和其他任何必须的状态转换。如果一个连接处于从网络 接收数据的状态,函数tcp_receive()将被调用。如果那样,tcp_receive()将把段上传给应用程序。 如果段构成未应答数据(先前放入缓冲区的)的ACK,数据将从缓冲被移走并且收回该存储区。同样, 如果接收到请求数据的ACK,接收者可能希望接收更多的数据,这时tcp_output()将被调用。图3 -3 TCP处理四、LWIP协议栈的内存管理4.1 LWIP协议栈中pbuf介绍TCP / IP是一种基于O S I参考模型的分层网络体系结构,它由应用层、运输层、网络层、数据 链路层、物理层组成。各层之间消息的传递通过数据报的形式进行。由于各层之间报头长度不一样, 当数据在不同协议层之间传递时,对数据进行封装和去封装、增加和删除操作将十分频繁。因此, 必须有一种能适应数据动态增删、但在逻辑上又呈现连续性的数据结构,以满足在各协议层之间传 递数据而不需要进行内存拷贝。嵌人式TCP/IP协议栈要求简单高效,并减少对内存的需求。这些 都需要相应的内存管理机制实现。LwI P利用pbuf结构实现数据传递,它与BSD中的Mbuf很相似。pbuf的主要用途是保存在 应用程序和网络接口间互相传递的用户数据。pbuf的内部结构为:struct pbufpbuf *next;*payload;tot_len;len;*指向下一个pbuf * /*指向p b u f数据中的起始位置* 1*该pbuf和后续pbuf中数据.长度的总和*/*该pbuf中数据的长度* /structvoidul6_tu16tu16-tflags;/ * pbuf 的类型* /ul6_tref;/ *该pbuf被引用的次数* /4.2 LWIP内存管理的实现在运行TCP/IP协议栈的嵌人式系统中,可以把整个系统的存储区域分为协议栈管理的存储器 和应用程序管理的存储器两部分。4.2.1协议栈管理的存储器协议栈管理的存储器是指TCP/IP内核能够操作的内存区域,主要用于装载待接收和发送的网络 数据分组。当接收到分组或者有分组要发送时,TCP/IP协议栈为这些分组分配缓存;接收到的分组 交付给应用程序或者分组已经发送完毕后,对分配的缓存回收重用。协议栈分配的缓存必须能容纳 各种大小的报文,例如从仅仅几个字节的ICMP回答报文到几百个字节的TCP分段报文。LWIP 中的 pbuf 有四种类型;PBUF_POOL、PBUF_RAM、PBUF_ROM、PBUF_REF。这四种类型的 pbuf 都是从TCP/IP协议栈管理的存储器中分配的,其中PBUF_ROM和PBUF_REF与应用程序管理的存储区 域密切相关。PBUF_POOL是具有固定容量的pbuf,主要供网络设备驱动使用,为收到的数据分组分 配缓存。在协议栈管理的内存中初始化了一个pbuf池(PBUF_POOL),具有相同尺寸的pbuf都是从这 个pbuf池中分配得到。一般使用多个PBUF_POOL链接成一个链表,用于存储数据分组。如图1所 示。next*next物payloadpayloadpayloadtokmtotjenlotj-enJenlenn略fl咿噂rtf研iwtu for link headerroom for IP headerrrom ior TCP Iteader图 4 T PBUF_POOL 链表LwIP用一个宏定义一个PBUF_POOL的大小。一个分组需要分 配几个PBUF_POOL,而在数据较少时分配一个PBUF_POOL即可。由 于分配一个PBUF_POOL类型的pbuf很快,适合在中断处理中使用, 所以PBUF POOL主要供网络设备驱动使用,为收到的数据分组分配 缓存。nejdused-1pW日或或prevuscdOnextpre%1used-1图4 - 2内存堆应用程序发送动态产生的数据时,可以用PBUF_RAM类型的 pbuf。PBUF_RAM在事先划分好的内存堆中分配。对该内存堆的操 作类似于C语言中的malloc/free。内存堆分配的结构如图4-2所 示。图2中每个被分配的存储块附带了一个小结构,该结构的两个 指针指向相邻的内存块。used标识位用来指示该内存块的分配情 况,阴影部分表示已经被分配了,此时used为1。当需要一块N 字节的存储块时,就对整个存储堆进行搜索。如果找到一块未用的 (used =0 )并且容量不小于N字节的区域就表示分配成功,并且置use为I。而分配的内存块使用 完后需要释放,为了不产生碎片,相邻且未用的内存块需要进行合并。PBUF_POOL和PBUF_RAM都可以根据需要从存储器中动态分配,这种分配机制又称为动态存储器 分配机制。该分配机制不仅能为应用程序的数据分配存储空间,而且能为协议首部分配存储空间。 在层与层之间传递数据时,真正需要修改的只是数据的格式,使之符合各层的规范,而数据本身不 需要变动。实际上数据格式反应的是各层的首部,当数据在各层之间传送时,需要动态地添加和移 去相应的首部,用动态分配机制可以很好地实现。4.2.1应用程序管理的存储器应用程序管理的存储器是指应用程序管理、操作的存储区域,二般从该区域为应用程序发 送数据分配缓存。虽然该存储区域不由TCP/IP协议栈管理,但在不严格分层的协议栈中,该存储 区域必须与TCP/IP管理的存储器协同工作。为节省内存,LWIP不采取分级访问模式,而是通过指 针访问数据。这样就不需要为数据的传递分配存储空间。应用程序发送的数据在交付LWIP后,LWIP 就认为这些数据是不能被改动的,因此应用程序的数据被认为是永远存在并且不能被改变的。这一 点与ROM很相似。类型名PBUF_ROM也由此而来。如图4-3所示,PBUF_ROM的数据指针payload指 向External memory(外部存储区)。External memory指不由TCP/IP协议栈管理的存储区,它可以 是应用程序管理的存储器为用户数据分配的缓存,也可以是ROM区域,如静态网页中的字符串常量 等。由于由应用程序交付的数据不能被改动,因此就需要动态地分配一个PBUF_RAM来装载协议的首图 4 - 3 PBUF RAM 与 PBUF ROM 的连接图4-3中的PBUF_ROM还可以是PBUF_REF。PBUF_REF和PBUF_ROM的特性非常相似,都可以 实现数据的零拷贝。但是当发送的数据需要排队时就表现出PBUF_REF的特性了。例如在发送分组时, 待发送的分组需要在ARP队列中排队,假如这些分组中有PBUF_ROM类型的pbuf,则说明该类型pbuf 中的数据位于应用程序的存储区域,是通过指针被PBUF_ROM引用的。这样直到分组被处理之前,被 引用的应用程序的这块存储区域都不能另作它用。在此情况下要用到PBUF_REF类型的pbuf。在排 队时,LWIP会为PBUF_REF类型的pbuf分配缓存(PBUF_POOL或PBUF_RAM),并将引用的应用程序的 数据拷贝到分配的缓存中。这样应用程序中被引用数据的存储区域就能被释放。pbuf结构实现了层与层之间的数据传递,但其非常消耗内存,并且需要TCP/IP协议栈为之分 配存储空间,例如协议控制udp_pcb,tcp-pcb等。通常,嵌人式TCP/IP协议栈都不是严格分层的, 尽量减少对内存的需求是实现嵌人式 TCP/IP的重点,内核的内存管理机制直接关系到嵌人式 TCP/IP协议栈的性能。五、LWIP的应用编程接口 (API)LwIP为我们提供了三种应用程序接口(API函数)来实现TCP/IP协议栈,它们分别是:1. low-level core / callback or raw API.是一种低水平的、基于回调函数的API (后面直接称RAW API),整个通信流程依靠协议栈里的 回调函数来驱动。因为回调函数的调用不能超越任务边界,这样应用程序和TCP/IP协议栈必须运 行在同一个任务中,而用户不再增加其它的任务,应用程序直接在TCP/IP任务空间运行。因此,就 要避免调用诸如挂起、等待的函数,以防止整个TCP/IP任务被挂起。RAW API接口函数不仅在程序代码的执行时间上更快,而且在运行中它也占用更少的 内存资源。唯一的缺点是应用程序的编写比较困难,并且代码较难理解。尽管如此,在CODE 和RAM都较小的嵌入式系统中,这也是我们优先考虑采用的方法。2. higher-level sequential API / LWIP API是一种高水平的、连续的API,LWIPAPI为我们提供了一种通用的方法,它与BSD标准的socket API非常相似,程序的执行过程同样是基于open-read-write-close”模型的,但操作相对低级。API 不需要在应用程序和协议栈之间复制数据,因为应用程序可以巧妙的直接处理内部缓冲区。(充分利 用LwIP的内部结构以实现其设计目标)因为BSD Socket API易于理解,并且很多应用程序为它而写,所以LwIP保留一个BSD Socket 兼容层是很有用的。尽管LwIP与BSD Socket API非常相似,但是它们之间仍然存在着值得注意 的区别,使用BSD Socket API的应用程序不必知道普通文件和网络连接的差别,而使用LwIP API 的应用程序就必须知道正在使用的是一个网络连接。它不适合于应用在比较小的嵌入式系统中,因 为它的实现要求应用程序必须支持多线程。从本质上讲,TCP/IP协议栈的通信过程是事件驱动的,因此,TCP/IP的代码和用户应用程序 的代码,应该在不同的线程里面。当然,在不同的应用程序中,这两种API我们可以同时采用。实 际上,sequential API就是一种利用RAW API来实现的一种属于协议本体的应用程序。3. BSD Socket APIBSD Socket API在连续的内存区域处理数据非常便于编写应用程序。因为应用程序内的数据处 理通常是在这样的连续内存区域内进行的。但是,对于LwIP,采用这种机制不具备任何优势。特别 是BSD Socket需要将要发送的数据从应用程序复制到TCP/IP协议栈的内部缓冲区。复制数据的 原因是应用程序与TCP/IP协议栈通常驻留在不同的受保护空间。大多数情况是应用程序是一个用 户进程,而TCP/IP协议栈则驻留在操作系统内核。通过避免额外的复制操作,API的性能可以大 幅度提升。同样,为了复制数据,系统还需要为此分配额外的内存,这样每一个信息包都需要使用 双倍的内存。虽然LWIP提供了一些接口函数,但操作相对低级,使用起来不方便,不利用于后续开发。由 于BSD SOCKET API很容易理解且己经有很多人为它写过应用程序,且应用程序使用BSD SOCKET API时候不需要知道普通文件和网络连接之间的差别,所以为了便要理解和应用,LWI提供了基于 LWIP接口函数的BSD SOCKET API,但没有任何容错机制,没有select()与poll()函数。以下就一些 重要的SOCKET API函数做一介绍。(1) socket()函数用于创建网络通信的套接字,并返回该套接字的整数描述符。函数原型为intsocket(int domain, int type, int protocol),其中参数 domain 代表协议族或地址族,对于 TCP/IP 为 PF_INET 或 AF_INET; type 代表服务类型,对于 TCP 为 SOCK_STREAM(流式),对于 UDP 为 SOCK DGRAM(数据报);protocol代表使用的协议号,对于 TCP为IPPROTO_TCP,对于 UDP为 IPPROTO_UDP,传递0表示根据协议族和给定的服务类型选择默认的协议号。若socket成功返回, 返回大于或等于0的有效套接字描述符,返回一 1表示发生了差错。(2) bind()函数将BSD socket绑定到本地(本机)地址上。在调用bind()时,本地IP地址和端口号将被 指定。connect()允许调用者为先前创建的套接字指明远程端点的地址。如果套接字使用TCP,该函数就 使用三次握手建立连接;如果套接字使用UDP,则仅指明远程端点,但不向它传送任何数据报。listen()使套接字处于被动状态(即准备接受传入的连接请求)。在服务器处理某个请求时,协议软 件应将后续收到的请求排队,listen也设置排队的连接请求的数目。listen只用于TCP套接字。accept()函数被用来等待TCP socket 口上的输入连接。在此之前,这个TCPsocket 口通过调用 listen()已经被设置成监听状态,对accept()调用一直被阻塞,直到与远程主机建立连接。(6) send()数在UDP和TCP两种连接中被用来发送数据。在调用send()前,数据接收器必须被设置 成正在使用connect(),应用程序在调用send()后可以直接修改发送的数据。sendto()调用函数与send()调用函数类似,但是在参数调用中他们允许应用程序指定数据接收器。 sendto()仅能在UDP连接中使用,实现这功能要使用netconnconnect()来设置数据包接收器。如果 以前socket 口被连接,必须重设远程IP地址和端口号。(8) write()调用函数通过连接来发送数据并且能在UDP和TCP连接中使用。参考文献1 W.Richard Stevens著.TCP/IP详解 卷1:协议.范建华等译.机械工业出版社.20002 Gary R.Wright,W.Richard Stevens著.TCP/IP详解卷2:实现.陆雪莹等译.机械工业出版 社.20003 W.Richard Stevens著.TCP/IP 详解卷三:TCP 事务协议,HTTP,NNTP和UNIX域协议.胡谷雨,昊礼发等译.机械工业出版社.20003 Jan Axelson,编著.嵌入式Ethernet和internet通信设计技术.骆丽,张岳强,欧小龙译.北京:北京航空航天大学出版社,2006.14 焦海波,刘健康.编著.嵌入式网络系统设计一基于Atmel ARM7,北京:北京航空航天大学 出版社,2008.45 Adam Dunkels. Design and Implementation of the lwIP TCP/IP Stack, Feb 20, 20016 Jea.Labrosse.编著.嵌入式实时操作系统uC/OS-II(第二版).邵贝贝等译.北京:北京航空航天大 学出版社,2003.57 Douglass E.Comer,David L.Stevens著.用TCP/IP进行网际互连 第二卷一设计、实现与内核:ANSIC版(第三版).张娟 王海等译北京:电子工业出版社,2008.108 BSD Sockets Interface ProgrammersGuide Edition 6. HP Company9 Guido Moritz, Steffen Pru ter, Web services on Deeply Embedded Devices with Real-Time Processing Proc on ETFA 08. IEEE10 邱书波,陈伟,基于ARM的轻量级TCP/IP协议栈的研究及移植计算机应用与软件,2009.811 王海波,基于以太网的LED图文显示系统的设计,大连理工大学硕士学位论文,2006.1211 彭义波,uCOS与TCPIP协议栈的分析与移植,华中师范大学硕士学位论文,2005.612 付晓军,夏应清,何轩,嵌入式LWIP协议栈的内存管理,嵌入式技术,2005.10和以下相关网站:http:/savannah.nongnu.org/projects/lwip
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 解决方案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!