OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4585|回复: 1

W7500 M0+MAC+TCP/IP 以太网单芯片方案 W7500 W7500EVB用户手册连载(23)--网络篇

[复制链接]

28

主题

86

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
317
金钱
317
注册时间
2018-2-23
在线时间
37 小时
发表于 2018-3-24 18:36:05 | 显示全部楼层 |阅读模式
W7500(W7500P)芯片简介:
W7500 芯片为工业级以太网单芯片解决方案, 集成 ARM Cortex-M0,128KB Flash 及全硬件TCP/IP 核(和W5500、W5100内核一致),特别适用于物联网领域。 使用 W7500EVB, 让您轻松完成原型开发。

全硬件TCP/IP核的最大优点是他在执行联网操作时不需要占用MCU的运行资源,大大增加了MCU的工作效率。


本节我们将实现一个HTTP服务器程序,也就是平时我们所说网页服务器。其实,这种嵌入式设备内嵌的网页服务器在我们日常生活中十分常见,例如我们生活中使用的无线路由器。我们在配置无线路由器时,都会使用浏览器打开其配置页面进行配置。这里我们使用的就是无线路由器里面内嵌的网页服务器功能。使用前,我们先了解下HTTP协议。


想了解更多关于WIZnet W7500更多信息,或者有技术问题请联系我们:gustin@wisioe.com
深圳炜世科技—WIZnet官方代理商,全程技术支持,价格绝对优势!
电话:0755-86568556
邮箱:support@wisioe.com
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

28

主题

86

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
317
金钱
317
注册时间
2018-2-23
在线时间
37 小时
 楼主| 发表于 2018-3-24 18:37:02 | 显示全部楼层
第二十四章 HTTP Server24.1 HTTP Server例程概述
       本节我们将实现一个HTTP服务器程序,也就是平时我们所说网页服务器。其实,这种嵌入式设备内嵌的网页服务器在我们日常生活中十分常见,例如我们生活中使用的无线路由器。我们在配置无线路由器时,都会使用浏览器打开其配置页面进行配置。这里我们使用的就是无线路由器里面内嵌的网页服务器功能。使用前,我们先了解下HTTP协议。
24.2 HTTP协议简介
超文本传输协议 HTTP(Hypertext transfer protocol) 是一种详细规定了浏览器和万维网服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议。也就是说我们在浏览器上看到的所有信息都是通过HTTP协议通讯的。
       超文本传输协议(hypertext transport protocol)简称HTTP,是一种通信协议,它使用TCP协议工作,默认端口号为80。它允许将超文本标记语言(HTML1)文档从WEB服务器传送到WEB浏览器。HTML是一种创建文档的标记语言,这些文档包含相关信息的链接。可以单击一个链接来访问其它文档、图像或多媒体对象,并获得关于链接项的附加信息。
       HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(NextGenerationofHTTP)的建议已经提出。HTTP协议的主要特点可概括如下:
1.支持客户/服务器模式。
2.简单快速:客户向服务器请求服务时,只需发送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type
加以标记。
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,则会断开连接。采用这种方式可以节省传输时间。
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
24.3 HTTP协议请求与响应
       Http是一个基于请求/响应模式的、无状态的协议。即我们通常所说的Request/Response。
       1.HTTP URL
HTTP URL格式如下: http://host[“:”port][abs_path]
       其中HTTP表示要通过HTTP协议来定位网络资源。host表示合法的Internet主机域名或IP地址。port用于指定一个端口号,拥有被请求资源的服务器主机监听该端口的TCP连接,如果port是空的,或者没有给出,则使用默认的缺省值80.abs_path表示指定请求资源的URI(Uniform Resource Identifier,统一资源标示符),如果URL中没有给出abs_path,那么当他作为请求URI时,必须以”/”的形式给出。通常,这个工作就由浏览器帮助我们完成了。当我们在浏览器中输入www.cnblogs.com时,然后回车,浏览器会自动将我你们输入的地址转换成http://www.cnblogs.com/,注意最后的斜杠“/”.
2. HTTP 请求
       客户端通过发送HTTP请求向服务器请求对资源的访问,HTTP由三部分组成,分别是:请求行,消息报头,请求正文。
       请求行:请求行以一个方法符号开头,后面跟着请求URI和协议的版本,以CRLF作为结尾。请求行以空格分隔,除了作为CRLF外,不允许出现单独的CR或者LF字符。具体格式为:Method Request-URI HTTP-Version CRLF
       Method表示请求方法,Request-URI是一个统一资源标示符,表示了要请求的资源,HTTP-Version表示请求的HTTP协议的版本号,CRLF表示回车换行。例如:GET /form.html HTTP/1.1 (CRLF)
0.JPG
图24.3.1 http常用请求方式
       GET方法用于获取由Request-URI所表示的资源信息,常见形式是:GET Request-URI HTTP/1.1
       我们通过在浏览器地址栏中直接输入网址的方式去访问网页的时候,浏览器采用的就是GET方法向服务器获取资源信息。
       POST方法用于向目的服务器发出请求,要求服务器接收附在请求后面的数据。POST方法在表单提交的时候用的较多。
一个采用POST方法提交的例子:
POST /form.html HTTP/1.1 (CRLF)
Accept:image/gif,application/json(…省略很多) (CRLF)
Host:www.abc.com (CRLF)
Content-Length:22 (CRLF)
Connection:Keep-Alive (CRLF)
Cache-Control:no-cache (CRLF)
(CRLF) //注意:空行上部是消息报头,下方是请求正文,这个空行是必须的。
user=zhangsan&password=123456
       HEAD方法与GET方法几乎一样,他们的区别在于HEAD方法只是请求消息报头,而不是完整的内容。对于HEAD请求的回应部分来说,它的HTTP头部中包含的信息与通过GET请求所得到的信息是相同的。利用这个方法,不必传输整个资源的内容,就可以得到Request-URI所表示的资源信息。这个方法常被用来测试超链接的有效性,是否可以访问,以及最近是否更新。
3. HTTP响应
在接收和处理消息后,服务器会返回一个HTTP响应消息。与HTTP请求类似,HTTP响应也由三个部分组成,分别是:状态行,消息报头,响应正文。
状态行:状态行由协议版本、数字形式的状态码、及响应的状态描述组成,各元素之间以空格分隔,除了结尾的CRLF(回车换行)之外,不允许出现CR或LF字符。格式如下:HTTP-Version Status-Code Reason-Phrase CRLF
       HTTP-Version表示服务器HTTP协议的版本,Status-Code表示服务器发回的响应代码。Reason-Phrase表示状态码的文本描述,CRLF表示回车换行。例如:HTTP/1.1 200 OK (CRLF)
1.JPG
图24.3.1 http响应状态
24.4 HTTP Server例程解析
本节我们就用W7500EVB建立自己一个网页服务器,你只在浏览器地址栏里键入W7500EVB的IP地址,就成功在你的网页上显示出来自己内嵌的网页了。
HTTP Server例程将HTTP协议的实现分为3个文件,main.c主文件实现主函数的调用,httputil.c文件用于接收http请求报文和发送http响应报文,http_server.c用于实现对请求报文的解析。我们调用的其它函数已经在其他应用程序中声明。
现在来看httpServer_run()函数:
[mw_shl_code=applescript,true]1.     void httpServer_run(uint8_t seqnum)
2.     {
3.       uint8_t s;     // socket number
4.       uint16_t len;
5.       uint32_t gettime = 0;
6.       http_request = (st_http_request *)pHTTP_RX;      // 定义http请求的结构体参数
7.       parsed_http_request = (st_http_request *)pHTTP_TX;
8.       s = getHTTPSocketNum(seqnum);                // 得到socket number
9.       switch(getSn_SR(s))                                //获取socket状态
10.    {
11.      case SOCK_ESTABLISHED:                         //socket初始化状态
12.        if(getSn_IR(s) & Sn_IR_CON)
13.        {
14.          setSn_IR(s, Sn_IR_CON);                     //清除中断标志位
15.        }
16.        switch(HTTPSock_Status[seqnum].sock_status)      // HTTP进程状态
17.        {
18.          case STATE_HTTP_IDLE :                           //IDLE等待数据接收状态
19.            if ((len = getSn_RX_RSR(s)) > 0)
20.            {
21.              if (len > DATA_BUF_SIZE) len = DATA_BUF_SIZE;
22.              len = recv(s, (uint8_t *)http_request, len);//接受请求消息
23.              *(((uint8_t *)http_request) + len) = '\0';  //解析接收到的请求信息包
24.              parse_http_request(parsed_http_request, (uint8_t *)http_request);
25.              http_process_handler(s, parsed_http_request);    // http相应处理
26.              gettime = get_httpServer_timecount();  //得到http服务器超时时间
27.              else
28.                HTTPSock_Status[seqnum].sock_status = STATE_HTTP_RES_DONE; // 发送http响应
29.            }
30.          break;
31.          case STATE_HTTP_RES_INPROC :        //从http客户端接收http请求状态
32.            /* Repeat: Send the remain parts of HTTP responses */
33.            send_http_response_body(s, 0, http_response, 0,0);//重复给客户端发送保留的数据
34.            if(HTTPSock_Status[seqnum].file_len == 0)
35.              HTTPSock_Status[seqnum].sock_status = STATE_HTTP_RES_DONE;//http响应结束
36.          break;
37.          case STATE_HTTP_RES_DONE ://http响应结束状态
38.            HTTPSock_Status[seqnum].file_len = 0;
39.            HTTPSock_Status[seqnum].file_offset = 0;
40.            HTTPSock_Status[seqnum].file_start = 0;
41.            HTTPSock_Status[seqnum].sock_status = STATE_HTTP_IDLE;
42.            http_disconnect(s);
43.          break;
44.          default :
45.          break;
46.        }
47.      break;
48.      case SOCK_CLOSE_WAIT:                   //socket等待关闭状态
49.        disconnect(s);
50.      break;
51.      case SOCK_CLOSED:                           //socket关闭状态
52.        socket(s, Sn_MR_TCP, HTTP_SERVER_PORT, 0x00);//初始化socket
53.      break;
54.      case SOCK_INIT:                                //socket初始化完成状态
55.        listen(s);                                  //服务器监听客户端
56.      break;
57.      case SOCK_LISTEN:                            //socket监听状态
58.      break;
59.      default :
60.      break;
61.    }
62.  }[/mw_shl_code]

函数httpServer_run();是一个典型的一次数据包TCP处理状态机。程序中第3行定义W7500EVB的一个HTTP的socket,实现http通信。第6行定义一个HTTP Request的结构体指针。由于HTTP通信支持TCP协议,在http通信过程中我们就按照socket的TCP状态来写程序。第64行,当处于socket初始化完成状态时,W7500EVB进行端口监听。第67行,当W7500EVB的socket监听状态时,直接跳出循环。第11行,当socket连接建立时,首先把Sn_IR的第0位置1(清除接收中断),然后进入switch判断HTTP的进程状态,第18~39行是等待数据接收状态,在该状态里判断socket接收到的数据不为0就接收请求信息并解析接收到的请求信息包然后对http做出相应处理。第43行是当客户端接收请求就重复给客户端发送保留的数据。第47行是http的响应结束状态进入该转态后会清空结构图并准备关闭socket。第41行,接收http请求报文。因为HTTP定义每次连接处理一个请求。第61行是socket关闭状态,初始化socket的80端口,并配置为TCP模式。
至此,HTTP Server例程解析到此结束,编译后将例程烧录查看打印串口信息结果为图24.4.1:
2.JPG
图24.4.1 HTTP Server例程打印结果
       打开浏览器在地址栏输入我们配置的W7500EVB的IP地址,查看例程结果。结果为图24.4.2。
3.JPG
图24.4.2 W7500EVB服务器网页配置

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 22:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表