最后更新:2022-07-22 01:42:44 手机定位技术交流文章
参考:TCP/IP Stack Lwip的设计与实现:六长红的博客 - CSDN Blog
目录
17.BSD插座库
17.1个插座的表达
17.2分配一个插座
17.2.1接口()调用
17.3连接建立
17.3.1 bind()调用
17.3.2连接()调用
17.3.3听电话
17.3.接受()呼叫
17.4 发送和接收数据
17.4.1发送()电话
17.4.2调用geto()和 sendmsg()
17.4.3写()呼叫
17.4.4 recv()和read()调用
17.4.5调用recvfrom()和recvmsg()
18.代码实例
18.1使用API
18.2直接使用堆栈接口
参考
这部分利用LWIP API实现了一些简单的BSD socket API。这里所提供的实现仅仅作为参考,不期望在实际程序中使用。这里没有错误捕获的示例。
同样,这里实现不支持BSD接口API的 select()和 poll()函数,因为在LWIP API中没有用于实现它们的函数。为了实现这些函数,BSD插座实现将不得不直接与LWIP协议堆栈通信,而不是使用API。
在BSD接口API中,索克被代表为一般的文件描述符。文件描述符是一个能识别文件或网络连接的整数。在BSD插座API实现中,插座由netconn结构内部表示。因为BSD插座是由整数标识的,netconn变量存储在套接口[]中,这里,BSD插座标识符是索引中的索引。
scket()调用指定了BSD插座。scket()函数的参数用于确定所要求的接口类型。既然这里的socket API实现仅仅关系与网络sockets,所以这里的类型只是一个支持的插座类型。同样,只能使用UDP(SOCK_DGRAM)或TCP(SOCK_STREAM)插座。实现如下:
BSD socket API建立一个连接的调用非常类似于最小API的连接建立函数。这些调用的实现主要包括从一个socket的整数表示到最小API中使用的抽象连接的转换。
调用 bind()函数将BSD接口绑定到一个本地地址。 在 bind()调用中,已经确定了本地IP地址和端口号码,这里 bind()函数与LWIP API中的 netconn_bind()函数非常相似。
具体实现与上面类似。
listen()函数基本上与LWIP API的netconn_listen()函数相同,而且它只能用于TCP连接。唯一的不同在于BSD socket API允许应用确定待确定的连接队列(累积的)的大小。这对于LWIP来说不太可能,累积参数会被忽略。
accept()调用用来在一个TCP socket上等待连接进入,索克已经通过先调用 listen() 设置为 LISTEN 状态。accept()将封锁到远程主机的连接建立为止,参数是收听的结果参数,通过调用接受()设置。它们由远程主机的地址填入.
当建立一个新的连接时,LWIP函数 netconn_accept()返回新连接的连接手柄。 当远程主机的IP地址和端口号码被填入时,一个新的插座标识符被分配并返回。
在BSD接口API中,send()调用可以用于UDP和TCP发送数据。在调用 send()之前,数据接收器必须使用connect()来建立。对于UDP会话,send()在LWIP API中类似 netconn_send()的调用,但由于LWIP API需要一个清晰的分配缓冲器,在 send() 调用中必须分配和释放缓冲器。所以,一个缓冲会被分配,数据将被复制到分布缓冲器中。
LWIP API的netconn_send()函数不能用于TCP连接,因此 send() 使用 netconn_write() 作为 TCP 连接的实现方案。在BSD接口API中,在呼叫 send()后,应用程序可以直接修改发送的数据,因此,NETCONN_COPY标识符被传递到netconn_write(),以便数据被复制到堆栈内部缓冲器中。
Sendo()和 sendmsg()调用类似于 send()调用,但它们允许应用程序在调用参数中确定数据接收器。同时,Sendmsg()和 sendo()只能用于UDP连接。在实现中,使用netconn_connect()设置数据消息接收器,因此,必须将远程IP地址和端口号码分开,如果索克已经连接。这里没有介绍 sendmsg() 的实现。
在BSD接口API中,调用 write()发送数据到一个连接,它可以用于UDP和TCP连接。对于TCP连接,它直接映射到LWIP API的netconn_write()函数。对于UDP,BSD插座函数 write()与 send()等价。
在BSD接口API中,recv()和read()调用用于接收到连接接口的数据。它们也可以用于TCP和UDP连接。许多标识符可以通过 callingrecv()传输。这些 都 没有 取得 成果 。标识参数被忽略。
如果接收到的消息比所提供的内存区域大,则超出此区域的数据将无情地丢弃。
Recvfrom()和 Recvmsg()调用类似于 Recv()调用,但区别在于通过调用可以获取数据发送者的IP地址和端口号码。
recvmsg()的实现不再包括。
本节使用LWIP API来编写一个简单的网络服务器。应用程序代码如下。该应用程序只实现一个HTTP/1.0[BLFF96]服务的核心,这里是一个原则的列表,仅用于显示在实际应用中使用LWIP API。
该申请由一个单一过程组成,这个过程从网络中接收连接,响应HTTP请求,以及关闭连接。程序中有两个函数,完成必要的初始化和连接的建立,process_ connection()实现HTTP/1.0的小子集。一个相当直接的例子,如何使用最小的API来启动连接。使用netconn_new()创建连接后,连接被绑定到TCP端口80,并设置为LISTEN状态,在该状态中,将等待连接的到来。呼叫 netconn_accept(),当远程主机建立后,将返回netconn连接。在处理连接后使用 process_connection(),必须使用 netconn_delete()来释放 netconn。
在 process_connection(),通过呼叫 netconn_recv()接收一个netbuf,通过呼叫 netbuf_data()获取指向实际请求的数据的指针。这将返回指针,指向Netbuf的第一节,我们 希望 它 载有 这项 要求 。因为我们只读了请求的第一七封信,这不是一个不现实的假设。如果我们想阅读更多的数据,最简单的方法是使用 netbuf_copy()请求复制到连续内存中,他们在那里处理它。
这个简单的网络服务器只响应HTTP GET请求,并使用文件分隔器'/',当请求被确认,发出答复。我们用两个调用函数 netconn_write()发送HTML数据和HTTP头条。因为我们没有改变HTTP头或者HTML数据,因此,您可以在netconn_write()调用中使用NETCONN_NOCOPY标识符以避免任何形式的复制。
最后,连接被关闭,函数process_connection()返回。调用之后,连接结构体就被释放。
申请的C代码如下:
因为Web服务器的基本机制非常简单,因为它只接收一个请求并通过发送文件到远程主机完成服务,因此,它可以在基于堆栈接口的内部事件中实现非常好。同样,因为它不包括复杂的计算,TCP/IP处理不会延迟。下面的例子说明如何实现这样的应用程序。该应用程序的实现与上面的例子非常相似。
[ABM95] B. Ahlgren, M. BjÄorkman, and K. Moldeklev. The performance of a no-copy api for communication (extended abstract). In IEEE Workshop on the Architecture and Im-plementation of High Performance Communication Subsystems, Mystic, Connecticut,USA, August 1995.
[APS99] M. Allman, V. Paxson, and W. Stevens. TCP congestion control. RFC 2581, Internet Engineering Task Force, April 1999.
[BIG+97] C. Brian, P. Indra, W. Geun, J. Prescott, and T. Sakai. IEEE-802.11 wireless local area networks. IEEE Communications Magazine, 35(9):116{126, September 1997.
[BLFF96] T. Berners-Lee, R. Fielding, and H. Frystyk. Hypertext transfer protocol { HTTP/1.0.RFC 1945, Internet Engineering Task Force, May 1996.
[Cla82a] D. D. Clark. Modularity and e±ciency in protocol implementation. RFC 817, Internet Engineering Task Force, July 1982.
[Cla82b] D. D. Clark. Window and acknowledgement strategy in TCP. RFC 813, Internet
Engineering Task Force, July 1982.
[HNI+98] J. Haartsen, M. Naghshineh, J. Inouye, O. Joeressen, and W. Allen. Bluetooth: Vision,goals, and architecture. Mobile Computing and Communications Review, 2(4):38{45,October 1998.
[Jac88] V. Jacobson. Congestion avoidance and control. In Proceedings of the SIGCOMM '88Conference, Stanford, California, August 1988.
[LDP99] L. Larzon, M. Degermark, and S. Pink. UDP Lite for real-time multimedia appli-cations. In Proceedings of the IEEE International Conference of Communications,Vancouver, British Columbia, Canada, June 1999.
[MD92] Paul E. McKenney and Ken F. Dove. E±cient demultiplexing of incoming TCP
packets.In Proceedings of the SIGCOMM '92 Conference, pages 269{279, Baltimore,Maryland, August 1992.
[MK90] T. Mallory and A. Kullberg. Incremental updating of the internet checksum. RFC1141, Internet Engineering Task Force, January 1990.
[MMFR96] M. Mathis, J. Mahdavi, S. Floyd, and A. Romanow. TCP selective acknowledgmentoptions. RFC 2018, Internet Engineering Task Force, October 1996.
[Mog92] J. Mogul. Network locality at the scale of processes. ACM Transactions on ComputerSystems, 10(2):81{109, May 1992.
[Nab] M. Naberezny. The 6502 microprocessor resource. Web page. 2000-11-30.
URL: http://www.6502.org/[PP93] C. Partridge and S. Pink. A faster UDP. IEEE/ACM Transactions in Networking,1(4):429{439, August 1993.
[Rij94] A. Rijsinghani. Computation of the internet checksum via incremental update. RFC1624, Internet Engineering Task Force, May 1994.
[vB] U. von Bassewitz. cc65 - a freeware c compiler for 6502 based systems. Web page.
2000-11-30.URL: http://www.cc65.org/
[Zak83] R. Zaks. Programming the 6502. Sybex, Berkeley, California, 1983.
完整文本完成
本文由 在线网速测试 整理编辑,转载请注明出处。