前面我们实现了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服务器的初始化。

/* HTTP服务器初始化配置*/void Http_Server_Initialization(void)
{struct tcp_pcb *pcb = NULL;                           /* 生成一个新的TCP控制块 */pcb = tcp_new();                                   /* 控制块绑定到本地IP和对应端口 */tcp_bind(pcb, IP_ADDR_ANY, TCP_HTTP_SERVER_PORT);      /* 服务器进入侦听状态 */pcb = tcp_listen(pcb);                       /* 注册服务器accept回调函数 */tcp_accept(pcb, HttpServerAccept);  }

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

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

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

/* HTTP服务器信息处理回调函数 */
static err_t HttpServerCallback(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{char *data = NULL;if (p != NULL){       /* 更新接收窗口 */tcp_recved(pcb, p->tot_len);data =  p->payload;/* 如果是http请求,返回html信息,否则无响应 */if(p->len >=3 && data[0] == 'G'&& data[1] == 'E'&& data[2] == 'T'){tcp_write(pcb, htmlMessage, sizeof(htmlMessage), 1);}else{}pbuf_free(p);tcp_close(pcb);}else if (err == ERR_OK){return tcp_close(pcb);}return ERR_OK;
}

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

4、  结论  

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

欢迎关注:

LwIP应用开发笔记之七:LwIP无操作系统HTTP服务器相关推荐

  1. LwIP应用开发笔记之一:LwIP无操作系统基本移植

    现在,TCP/IP协议的应用无处不在.随着物联网的火爆,嵌入式领域使用TCP/IP协议进行通讯也越来越广泛.在我们的相关产品中,也都有应用,所以我们结合应用实际对相关应用作相应的总结. 1.技术准备 ...

  2. LwIP应用开发笔记之四:LwIP无操作系统TFTP服务器

    前面我们已经实现了UDP的回环客户端和回环服务器的简单应用,接下来我们实现一个基于UDP的简单文件传输协议TFTP. 1.TFTP协议简介 TFTP是TCP/IP协议族中的一个用来在客户机与服务器之间 ...

  3. LwIP应用开发笔记之六:LwIP无操作系统TCP客户端

    上一篇我们基于LwIP协议栈的RAW API实现了一个TCP服务器的简单应用,接下来一节我们来实现一个TCP客户端的简单应用. 1.TCP简述 TCP(Transmission Control Pro ...

  4. LwIP应用开发笔记之五:LwIP无操作系统TCP服务器

    前面我们实现了UDP服务器及客户端以及基于其上的TFTP应用服务器.接下来我们将实现同样广泛应用的TCP协议各类应用. 1.TCP简述 TCP(Transmission Control Protoco ...

  5. LwIP应用开发笔记之十:LwIP带操作系统基本移植

    现在,TCP/IP协议的应用无处不在.随着物联网的火爆,嵌入式领域使用TCP/IP协议进行通讯也越来越广泛.在我们的相关产品中,也都有应用,所以我们结合应用实际对相关应用作相应的总结. 1.技术准备 ...

  6. LwIP应用开发笔记之十一:LwIP带操作系统UDP服务器

      我们已经实现了在FreeRTOS系统上的LwIP的移植工作,但只是简单的在系统平台上跑了起来.我们还希望能做更多的事情,这一节我们就在FreeRTOS系统上实现基于LwIP的UDP服务器. 1.U ...

  7. LwIP应用开发笔记之九:LwIP无操作系统TELNET服务器

    前面我们已经实现了基于RAW API的TCP服务器和客户端,也在此基础上实现了HTTP应用.接下来我们实现一个基于TCP的Telnet服务器应用. 1.Telnet协议简介 Telnet协议是TCP/ ...

  8. LwIP应用开发笔记之八:LwIP无操作系统HTTP客户端

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

  9. LwIP应用开发笔记之二:LwIP无操作系统UDP服务器

    前面我们已经完成了LwIP协议栈基于逻辑的基本移植,在这一节我们将以RAW API来实现UDP服务器. 1.UDP协议简述 UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是 ...

最新文章

  1. 谷歌官方扩展UI组件---SlideTabLayout
  2. Canvas入门-利用Canvas绘制好玩的电子时钟
  3. 响应式的无限滚动全屏dribbble作品集布局展示效果
  4. 测试人员如何使用浏览器的f12_测试过程中如何快速定位一个bug
  5. 04 | 复杂度分析(下):浅析最好、最坏、平均、均摊时间复杂度
  6. android如何建立全局变量,如何在Android中声明全局变量?
  7. 【白皮书分享】快手私域经营白皮书.pdf(附下载链接)
  8. 【回顾】手机淘宝推荐系统实战
  9. TextView的一些高级应用(自定义字体、显示多种颜色、添加阴影)
  10. Windows平台上实现P2P服务(一)
  11. 无法启动此程序,因为计算机中丢失 的解决办法
  12. Linux 快速原型工具 Pencil
  13. PTAL1-087机工士姆斯塔迪奥
  14. 关于H.264 profile-level-id
  15. Linux线程ID与内核LWP的关系
  16. 开源网络准入软件packetfence 部署心得-1
  17. 传统数仓如何转型大数据
  18. 【RPA自动化|提升办公效率|懒人必备】微信自动点赞
  19. 丙烯的精制工艺及在线监测
  20. 区块链仿真工具SimBlock

热门文章

  1. 2020年跨行业跨领域工业互联网平台
  2. 国科大高级人工智能12-博弈
  3. redis笔记_源码_双端链表list
  4. Liunx之nginx代理
  5. 函数式编程让你忘记设计模式
  6. java 双因素认证(2FA)TOTP demo
  7. HBase:分布式列式NoSQL数据库
  8. 201521123059 《Java程序设计》第八周学习总结
  9. oracle数据库卸载(需要完全卸载oracl才能重装)
  10. Scala模式匹配和类型系统