0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于LwIP的HTTP服务器设计

CHANBAEK 来源:木南创智 作者:尹家军 2022-12-14 15:15 次阅读

前面我们实现了TCP服务器和客户端的简单应用,接下来我们实现一个基于TCP协议的应用协议,那就是HTTP超文本传输协议

1 ** HTTP****协议简介**

超文本传输协议(Hyper Text Transfer Protocol),简称HTTP,是一种基于TCP的应用层协议,也是目前为止最为流行的应用层协议之一,可以说HTTP协议是万维网的基石。

HTTP是一种客户端请求、服务器应答式的应用层传输协议,也就是说服务器端是不可能主动向客户端发送数据的。在网络正常的情况下请求和响应都是一一对应的。而这个请求和响应也就是后端开发人员经常看到的Request和Response。

首先,我们来看客户器端的请求,HTTP请求报文由请求行、请求头、空白行以及请求体组成。其报文格式如下:

我们来说一说请求行,它由请求方法字段、URL字段和HTTP协议版本字段3个字段组成,它们用空格分隔。需要理解的是请求方法,HTTP协议的请求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT几种。先对常用的几种说明如下:

  • GET 方法 ,意思是获取URL指定的资源,这个请求方式是最简单的也是最常用的。使用GET 方法时,可以将请求参数和对应的值附加在 URI 后面,利用一个问号(“?”)将资源的URI和请求参数隔开,参数之间使用与符号(“&”)隔开,因此传递参数长度也受到了限制,而且与隐私相关的信息也直接暴露在URI中。比如/index.jsp?username=holmofy&password=123123
  • HEAD 方法, 与GET用法相同,但没有响应体,使用场合没有GET多。比如下载前使用HEAD发送请求,通过ContentLength响应字段,来了解网络资源的大小;或者通过LastModified响应字段来判断本地缓存资源是否要更新。
  • POST 方法, 一般用提交信息或数据,请求服务器进行处理(例如提交表单或者上传文件)。表单使用POST相对GET来说还是比较隐秘的,而且GET的URL有长度限制,而上传大文件就必须要使用POST了。
  • OPTIONS 方法, 该方法用于请求服务器告知其支持哪些其他的功能和方法。通过OPTIONS 方法,可以询问服务器具体支持哪些方法,或者服务器会使用什么样的方法来处理一些特殊资源。可以说这是一个探测性的方法,客户端通过该方法可以在不访问服务器上实际资源的情况下就知道处理该资源的最优方式。这个选项在跨域HTTP请求的情况出现的比较多,这里有一篇关于跨域请求的文章,其中有一张图很好的解释了什么是跨域HTTP请求。

客户端发出HTTP请求,服务端接收后,会向客户端发送响应信息。所以接下来,我们来看看服务器端的响应报文。HTTP响应报文由响应行、响应头、空白行以及响应体组成。其报文格式如下:

在响应报文中,非常重要的就是响应行,其中响应行中最重要的就是HTTP的状态码。HTTP协议中状态码有三位数字组成,第一位数字定义了响应的类别,有以下五种:

  • 1XX 信息提示。表示请求已被服务器接受,但需要继续处理,范围为100~101。
  • 2XX 请求成功。服务器成功处理了请求。范围为200~206。
  • 3XX:客户端重定向。重定向状态码用于告诉客户端浏览器,它们访问的资源已被移动,并告诉客户端新的资源位置。客户端收到重定向会重新对新资源发起请求。范围为300~305。
  • 4XX 客户端信息错误。客户端可能发送了服务器无法处理的东西,比如请求的格式错误,或者请求了一个不存在的资源。范围为400~415。
  • 5XX:服务器出错。客户端发送了有效的请求,但是服务器自身出现错误,比如Web程序运行出错。范围是500~505。

我们开发过程有一些状态码比较常见,我们对其简单说明如下:

2 ** HTTP****服务器端的设计**

我们已经对基于RAW API的TCP应用有了了解。我们在实现TCP服务器的实验时就提到过对于更复杂的应用和应用层协议只是在功能上的差别,从实现的结构及流程来说是完全一致的。所以对于实现HTTP服务器需要使用到的函数及整个操作流程我们就不再叙述了。重点说一说不同的地方。

首先HTTP服务器是基于TCP的,所以其我们先将其当作TCP服务器来实现。需要注意的是,HTTP协议有其专门的操作端口:80。所以我们设计服务器时需要使用这个端口。

在这里,我们设计一个简单的HTTP服务器,当客户端连接到服务器之后,如果收到的是html请求,则返回一个我们预先设定好的网页。正常返回这个网页,HTTP的功能就完成了,HTTP服务器会主动断开与客户端的连接。

3 ** TTP****服务器实现**

既然是基于TCP的HTTP服务器,我们佷显然依然按照TCP服务器的结构来实现。我们依然将其划分为三个部分来实现。首先要实现的是HTTP服务器的初始化。

1 /* HTTP服务器初始化配置*/
 2  void Http_Server_Initialization(void)
 3 {
 4   struct tcp_pcb *pcb = NULL;                           
 5  
 6   /* 生成一个新的TCP控制块 */
 7   pcb = tcp_new();                                   
 8  
 9   /* 控制块绑定到本地IP和对应端口 */
10   tcp_bind(pcb, IP_ADDR_ANY, TCP_HTTP_SERVER_PORT);      
11  
12   /* 服务器进入侦听状态 */
13   pcb = tcp_listen(pcb);                       
14  
15   /* 注册服务器accept回调函数 */
16   tcp_accept(pcb, HttpServerAccept);  
17                                                                      
18 }

从上面的代码不难看出,与TCP服务器的初始化一样:建立控制块,为控制块绑定本地IP和端口,服务器监听控制块同时注册接收处理回调函数。所以接下来就是实现接收处理回调函数。

1 /* HTTP接收回调函数,客户端建立连接后,本函数被调用 */
2 static err_t HttpServerAccept(void *arg, struct tcp_pcb *pcb, err_t err)
3 {
4   /*注册HTTP服务器回调函数*/
5   tcp_recv(pcb, HttpServerCallback);
6  
7   return ERR_OK;
8 }

客户端连接成功后就会调用接收处理回调函数。该函数为tcp_accept_fn类型,注册到了监听控制块的accept字段。在这个函数中,我们需要注册HTTP服务器处理函数。其功能就由这个函数决定。

1 /* HTTP服务器信息处理回调函数 */
 2 static err_t HttpServerCallback(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
 3 {
 4   char *data = NULL;
 5  
 6   if (p != NULL)
 7   {       
 8     /* 更新接收窗口 */
 9     tcp_recved(pcb, p->tot_len);
10     data =  p->payload;
11    
12     /* 如果是http请求,返回html信息,否则无响应 */
13     if(p->len >=3 && data[0] == 'G'&& data[1] == 'E'&& data[2] == 'T')
14     {
15       tcp_write(pcb, htmlMessage, sizeof(htmlMessage), 1);
16     }
17     else
18     {
19  
20     }
21     pbuf_free(p);
22     tcp_close(pcb);
23   }
24   else if (err == ERR_OK)
25   {
26     return tcp_close(pcb);
27   }
28   return ERR_OK;
29 }

这个HTTP服务器非常简单,我们只是实现了GET方法。也就是说,收到客户端的html请求后,我们检测其要求,如果是GET方法,我们就返回预先设定好的网页,否则无返回。然后关闭这一连接。如果我们想要实现更复杂的功能,或者需要支持HTTP协议的其他方法,只需要扩展这个函数就可以了。

4 结论

HTTP协议是一种使用非常广泛的协议,其基于TCP基础上运行,所以在我们前面已经实现TCP服务器及客户端的情况下,开发HTTP服务器应用就显得简单了。在这一篇我们基于LwIP实现了一个简单的HTTP服务器应用,我们并对其进行了简单的测试,虽然我们只是实现了GET方法,但经测试设计是正确的。如果需要设计其他方法的HTTP应用只需在此基础上添加即可。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 服务器
    +关注

    关注

    12

    文章

    8294

    浏览量

    83187
  • HTTP
    +关注

    关注

    0

    文章

    467

    浏览量

    30439
  • TCP
    TCP
    +关注

    关注

    8

    文章

    1285

    浏览量

    78463
  • 传输协议
    +关注

    关注

    0

    文章

    69

    浏览量

    11363
  • LwIP
    +关注

    关注

    2

    文章

    82

    浏览量

    26730
收藏 人收藏

    评论

    相关推荐

    嵌入式__LWIP_WEB服务器

    嵌入式__LWIP_WEB服务器
    发表于 08-20 09:53

    如何用LWIP进行远程服务器连接

    平台F107+LWIP1.4.1情景:设备通过TCP去连接远程服务器问题:国内的服务器可以瞬间连接上(秒级),国外的服务器需要很长时间才可以连接上(分钟级)、但是电脑连接很快(秒级)不
    发表于 07-18 01:37

    请问UCOSIII的LWIP socket服务器要怎么写?

    请问哪位大神知道UCOSIII的LWIP socket 服务器要怎么写?求例程~~~
    发表于 09-24 04:36

    LWIP_UCOSIII TCP服务器分享!

    此次分享的 在上次TCP客户端的基础上 增加了TCP服务器端支持并发功能最大客户端数量 (默认为5个)同样参照原子大神 跟野火大神 的程序因本人水平有限 如有错误 请指正申明下 硬件平台F407+DM9161LWIP_UCOSIII.rar (1.49 MB )
    发表于 10-12 10:22

    测试echo服务器lwip时出现问题的解决办法?

    嗨,我想利用sdk测试echo服务器lwip,fpga程序并运行configration。但是,在控制台中,有一些行让我感到困惑。----- lwIP TCP echo服务器-----
    发表于 05-12 07:58

    STM32网页服务器LWIP websever ajax是由哪些部分组成的

    STM32网页服务器LWIP websever ajax的硬件是由哪些部分组成的?STM32网页服务器LWIP websever ajax的软件是由哪些部分组成的?
    发表于 02-22 06:39

    HTTP OTA webclient获取不到服务器如何处理?

    尝试用HTTP_OTA的方式来升级程序,按照网上的资料搭建程序,在http_ota.c中现在遇到Webclient获取不到服务器的情况:找不到服务器
    发表于 05-19 10:43

    在BL706上基于LwIP协议栈实现一个HTTP服务器

    是万维网的数据通信的基础。本 demo 主要是在 BL706 上基于 LwIP 协议栈,实现一个 HTTP 服务器,在 BL706 上部署了一个简单的网页,然后我们可以通过浏览去访
    发表于 07-04 18:13

    在NUCLEO-H743ZI板上通过STM32CubeMX生成的代码有问题求助

    STM32CubeMX 生成的配置中。硬件本身是好的。STM32Cube_FW_H7_V1.1.0 中有一个 LwIP HTTP 服务器示例,如果我将其上传到电路板,它就可以正常工作
    发表于 12-27 08:06

    我如何在LWIP HTTP服务器的示例中更改电源配置呢?

    我正在使用 LWIP HTTP 服务器的示例,由 STM here提供。但是,时钟配置将电源配置为 PWR_LDO_SUPPLY。但是,我的电路板配置为接受
    发表于 01-03 08:22

    如何基于HTTP Web服务器示例实现TLS HTTPS服务器

    我正在尝试基于此 HTTP Web 服务器示例实现 TLS HTTPS 服务器:https://github.com/STMicroelectronics/x-cube-azrtos-h7/tree
    发表于 01-04 06:23

    HTTP服务器fsdata_custom.c项目问题求解

    我正在尝试创建一个 http 服务器。我使用 makefsdata.exe 创建 fsdata.c 文件。然后我从项目的编译中排除这个文件。但是,该项目在尝试构建项目时会抛出
    发表于 01-11 06:20

    HTTP服务器使用uIP TCP/ IP堆栈的示例

    EC_ M480_ uIP_ HTTP_Led_V1. 00 显示 HTTP 服务器, 网页非常简单 。 HTTP 客户端, 例如 IE 或 Chrome , 可以通过超链接连接到
    发表于 08-22 07:07

    【程序】Marvell 88W8801 WiFi模块连接路由器,并使用lwip2.0.3建立http服务器(20190314版)

    【程序】Marvell 88W8801 WiFi模块连接路由器,并使用lwip2.0.3建立http服务器(20190314版)
    发表于 11-21 19:21 0次下载
    【程序】Marvell 88W8801 WiFi模块连接路由器,并使用<b class='flag-5'>lwip</b>2.0.3建立<b class='flag-5'>http</b><b class='flag-5'>服务器</b>(20190314版)

    基于LwIP的UDP服务器设计

    我们已经实现了在FreeRTOS系统上的LwIP的移植工作,但只是简单的在系统平台上跑了起来。我们还希望能做更多的事情,这一节我们就在FreeRTOS系统上实现基于LwIP的UDP服务器
    的头像 发表于 12-14 15:39 1295次阅读
    基于<b class='flag-5'>LwIP</b>的UDP<b class='flag-5'>服务器</b>设计