W3150A+评估板--EVB-PIC24 用户手册(三)
0赞昨天给大家讲了关于W3150A+评估板--EVB-PIC24 关于程序员指南中,关于内存映射和EVB B/D固件的编译及管理程序的一些内容。
今天给大家介绍 程序员指南中,关于EVB B/D固件中应用的问题,包含回路程序, 网络服务器,和DHCP 客户端. 通过管理程序选择应用.
3.2.6. 应用
它是一个用iinChip™的网络应用,它包含回路程序, 网络服务器,和DHCP 客户端. 通过管理程序选择应用.
3.2.6.1. 回路 TCP 服务器
回路TCP服务器程序中, EVB B/D 工作在服务器模式, AX1, PC 测试程序工作在客户端模式. AX1 连接到EVB B/D, 如果连接成功, AX1 通过 TCP信道发送数据流. EVB B/D通过TCP信道不经过处理发挥数据流.
回路TCP 服务器程序使用loopback_tcps() , <图 3.14> 展示了loopback_tcps()的处理流程.
<图 3.14 : loopback_tcps() >
<表 3‑23: loopback_tcps()中的参考函数>
如果服务器socket在SOCK_CLOSED 状态,loopback_tcps()用Sn_MR_TCP, 监听端口号和 Option Flag等元素调用socket() 来创建TCP服务器socket.
socket() 函数改变socket状态为SOCK_INIT而不顾原来的socket状态.如果服务器socket创建成功, 在以参数用服务器socket调用listen()之后,它处于TCP 服务器模式.listen()使得服务器socket 状态为监听状态并保持坚挺状态直到任何客户端的连接.
此时, 当任一客户端尝试连接到服务器socket时,服务器 socket 状态从 “listen” 改为 “established”. 此时客户端和服务器之间的连接建立,在SOCK_ESTABLISHED状态可以进行数据传送.
数据的传送在SOCK_ESTABLISHED中使用 recv() 和send()实现.这里的数据传送是EVB B/D(服务器) 和AX1(客户端)之间1对1的传送.
在SOCK_ESTABLISHED状态,如果客户端请求关闭连接, 服务器 socket状态将从 SOCK_ESTABLISHED 改变为SOCK_CLOSE_WAIT. 在SOCK_CLOSE_WAIT 状态,不能进行数据通信并且必须关闭服务器 socket. 在 SOCK_CLOSE_WAIT状态, 调用disconnect() 关闭socket. disconnect() 改变socket 状态为SOCK_CLOSED 而不顾以前的socket状态.
3.2.6.2. 回路 TCP 客户端
在 回路TCP 客户端程序, EVB B/D 工作在客户端模式 , AX1, PC 测试程序工作在服务器模式. EVB B/D 尝试连接到以服务器状态等待的 AX1, 如果连接成功,EVB B/D 通过TCP 信道接收数据流, 然后 EVB B/D将接收到的数据流不经过处理发送给AX1.
回路 TCP 客户端程序是用 loopback_tcpc() 创建的, <图3.15>是loopback_tcpc()处理的进程.
如果客户端socket在SOCK_CLOSED 状态, loopback_tcpc()用Sn_MR_TCP, Any Port Number和Option Flag等元素调用socket()以创建TCP客户端socket.
这里调用socket, get_system_any_port()使用任意端口号. 这是因为如果用同样的端口号尝试连接到同样的服务器连接有可能失败. 成功创建socket后, 用服务器socket的元素调用 connect()以连接到AX1服务器.
connect()使得socket状态变成SOCK_SYNSENT,并使状态保持在SOCK_SYNSENT直到收到来自服务器的链接授权. 如果连接成功,socket状态从SOCK_SYNSENT改变为SOCK_ESTABLISHED. 在 SOCK_ESTABLISHED 状态,操作和loopback_tcps()一样.
<图 3.15: loopback_tcpc()>
<表 3‑24: loopback_tcpc()中的参考函数>
3.2.6.3. 回路 UDP
回路UDP 程序用UDP协议的单播数据报通信.它的操作和回路TCP 服务器/客户端 程序一样. UDP 通信包括单播数据报通信和广播数据报通信, 基本上支持用一个信道实现多目的地的1到多通信.
回路 UDP 程序使用loopback_udp() , <图 3-16> 是 loopback_udp()处理进程.
<图 3.16: loopback_udp()>
<表 3‑25: loopback_udp()的参考函数>
如果udp socket 在 SOCK_CLOSED 状态, socket() 用Sn_MR_UDP, Port Number和Option Flag等元素调用以创建UDP socket.
UDP通信和TCP相反, 是不需要连接进程请求的数据报通信. 因此在socket建立后可立刻进行直接数据通信. 在创建 UDP socket后, udp socket 的状态将从SOCK_CLOSED改为SOCK_UDP.
这里, 不像TCP 数据通信使用send() 和recv(), 而是使用sendto()和ecvfrom().
这是因为TCP是已知目的地的一对一通信方法,但是UDP是不需要连接进程的一对多通信. sendto()发送数据到特定目的地的特定端口, recvfrom() 用于接收来自临时端口的入数据. 来自recvfrom()的目的信息将被用目的地址和目的端口告知用户,目的地址和目的端口以元素的形式发送.
在loopback_udp()中, 没有使用close()的例子, 但是万一不再需要UDP 通信, 同样可以调用close() 并关闭udp socket.
3.2.6.4. 网络服务器
网络服务器程序是一个TCP服务器程序,它使用基于TCP协议的HTTP协议. 在创建网络服务器程序之前, 需要理解在网络服务器和网络客户端(网络浏览器)之间发送的HTTP协议消息结构.HTTP, 是超文本传输协议的缩写,用于基于因特网的网络服务器和客户端浏览器之间的传输协议.
<表 3‑26: 网络浏览器的 HTTP 请求运行进程 >
网络服务器程序分析从网络浏览器接收到的 HTTP请求消息的方法和URI(统一资源标识符), 如果相关的URI只是简单的请求网页, 就发送网页. 如果请求是诸如CGI(公共网关接口)的动作,就接收该动作并在网页中显示结果.
<图 3.17> 是网络服务器和网络客户端之间的HTTP 消息流,<表 3-28> 是HTTP消息结构.
<图 3.17: HTTP 消息流>
<表 3‑27: HTTP消息格式>
想了解更多有关HTTP消息的信息,请参考 RFC2616. HTTP 请求消息随着网络浏览器的不同而不同.
<表 3-29> 是Windows 2000上的Internet Explores和EVB B/D的HTTP消息通信.
<表 3‑28: EVB B/D和网络浏览器之间的HTTP消息>
网络浏览器程序由管理HTTP服务器socket的web_server()和管理HTTP消息的 proc_http() 组成。
<图 3.18> 是处理进程.
<图 3.18: web_server()>
因为web_server() 是TCP服务器程序,它的创建和Chapter 3.2.6.1所解释的loopback_tcps()相似. Difference between web_server()和loopback_tcps() 不同之处在于数据通信代码. web_server() 调用 proc_http(),proc_http()处理来自在http socket的SOCK_ESTABLISHED上的网络浏览器的HTTP请求消息.
在调用proc_http()函数后, web_server()处于等待状态,知道收到来自网络浏览器的HTTP请求消息的HTTP 回复消息, 然后调用 disconnect() 关闭 http socket.
这种 socket 关闭叫做Active Close, 在这种情况下, EVB B/D 先请求关闭客户端. 如果你喜欢,也可使用 Passive Close,它是客户端先提出断开连接请求. 网络浏览器支持Active Close的原因是因为 EVB B/D 支持其他客户端的链接.
<图 3.19: proc_http()>
proc_http() 调用 parse_http_request() 以分析接收到的网络浏览器的 HTTP 请求消息.被分析的HTTP请求消息的METHOD是“GET”, “HEAD”或 “POST”, 将调用get_http_uri_name()并且URI Name将从HTTP请求消息中提取出来.如果提取的URI Name是“/” ,就用“index.html”代替URI Name “/” ,“index.html”是EVB B/D 的网络浏览器默认页面,因为这意味着网络浏览器在请求网络服务器的默认页面.
通过调用find_http_uri_type()获得HTTP请求消息的HTTP Request Type之后,如果HTTP Request Type是 “CGI” ,就执行相关的 CGI 命令进程.
在处理CGI 命令后,或HTTP Request Type不是CGI, 用内置在EVB B/D 的ROM File Image的URI Name搜索文件.
如果找到了文件, 创建 HTTP回复消息并发送.
HTTP回复消息由HTTP Response Header 传送和HTTP Response Body传送组成. 传送 HTTP Response Header时, 用HTTP Request Type作为元素调用make_http_response_head() 以创建 HTTP Response Header. 传送完已创建的HTTP Response Header后,再传送HTTP Response Bodyd. 例如, 如果 HTTP Response body 是 ROM File Image中的任意文件, 则比iinChip™的 MTU大得多. 因此在传送之前需要分开为iinChip™的最大大小. 此时,如果定义在EVB B/D中的系统环境变量存在于 HTTP Response Body 中, 就调用 replace_sys_env_value() 并用存储在EVB B/D中的系统环境值代替系统环境变量.
<表 3‑29: “evbctrl.html” 系统环境变量使用>
<表 3-30> EVB B/D的ROM File Image的部分“evbctrl.html”.
系统环境变量的长度被定义成将被替代的系统环境值的长度. 例如, 如果EVB的源IP地址是最长16位的字符串. 因此 $SRC_IP_ADDRESS$的长度也是16. EVB B/D 的‘ROM File System’ 可用WIZnet提供的 “ROMFileMaker.exe”创建. 请参考 “ROM File Maker Manual Vx.x.pdf” 以获得更多信息.
HTTP 请求消息能通过parse_http_request()分成 Method和Request-URI ,并存储在<表 3-31>定义的 ‘st_http_request’ Date Type中. 它用get_http_uri_type()得到请求URI Type.
<表 3‑30: “st_http_request” 数据>
<图 3.20: parse_http_request()>
<图 3.21: find_http_uri_type()>
Request-URI 保存在st_http_request 的URI [MAX_URI_SIZE]中,它在“?”符号前有 URI Name,在“?”符号后有Query String. 当 Request-URI 从网络浏览器传送到网络服务器时, SP(Space)以‘+’的形式发送,其他Reserved Texts 以“%HEXHEX”的形式发送.相应地, Request-URI中的Reserved Texts需要被译码成原来的值, 从 ‘+’ 到 SP,从%HEXHEX到相应的ASCII值. Request-URI译码的详细信息请参考RFC1738.用get_http_uri_name()提取Request-URI的URI name. Request-URI的Query String 可以包含一到多个用“&”作为分隔符的 “variable=value” 对. 通过get_http_param_value()函数,可以在Query String提取相应的变量值.
<图 3.22: get_http_uri_name() & get_http_parse_value()>
Web Server Program EVB B/D网络浏览器程序的CGI处理和一般的基于OS的网络浏览器程序不相同.基于OS的网络浏览器程序创建单独的进程独立地处理处理器之间的通信. 然而, EVB B/D网络服务器是无操作系统的, 因此它不是创建独立的进程, 而是调用相关函数直接进行CGI处理. EVB B/D 支持更新网络信息的 “NETCONF.CGI” 以及控制文本LCD和EVB B/D D1/D2 LED 的“LCDNLED.CGI” .<图 3.23>和 <图 3.24> 是两个CGI进程图.
<图 3.23: NETCONF.CGI 处理>
<图 3.24: LCDNLED.CGI 处理>
NETCONF.CGI的