C语言编写Http服务器中Request的解析,让一些从零开始

栏目: C · 发布时间: 6年前

内容简介:如果你能完成一个简单的基于TCP/IP的socket server 程序,那么恭喜你,本文你可以好好读一读。HTTP正式基于TCP/IP的应用层协议,所以只要我们的程序能读懂HTTP数据,并做出符合HTTP协议的响应,那么就能完成HTTP的通信。如果你有机会,可以常识使用telnet连接我们的服务器,你将的得到得是一些没有意义的字符。如果是浏览器,会传送什么呢?我们试着在浏览器地址栏输入我们的服务器地址: 127.0.0.1:9734 后访问,发现浏览器说“127.0.0.1 发送的响应无效。”, 那是说

制作流程

  • 观察收到的http数据
  • 解析 request 的 method url version
  • 解析 header
  • 解析 body

观察收到的http数据

C语言编写Http服务器中Request的解析,让一些从零开始

如果你能完成一个简单的基于TCP/IP的socket server 程序,那么恭喜你,本文你可以好好读一读。HTTP正式基于TCP/IP的应用层协议,所以只要我们的程序能读懂HTTP数据,并做出符合HTTP协议的响应,那么就能完成HTTP的通信。

如果你有机会,可以常识使用telnet连接我们的服务器,你将的得到得是一些没有意义的字符。如果是浏览器,会传送什么呢?我们试着在浏览器地址栏输入我们的服务器地址: 127.0.0.1:9734 后访问,发现浏览器说“127.0.0.1 发送的响应无效。”, 那是说我们返回给浏览器的数据浏览器读不懂,因为现代的浏览器默认用http协议请求访问我们的服务器,而我们的返回的数据只是"helloworld"字符串,并不符合http协议的返回格式。虽然如此,但浏览器却是很有诚意的给我们的服务器发标准的http请求,不信我们看下我们的服务器收到的信息:

C语言编写Http服务器中Request的解析,让一些从零开始

先观察一会儿,看起来第一行是http请求的类型,第二行开始是一些":"号分割的键值对。的确如此,第一行告诉我们是用的GET请求,请求的url是"/",用的是1.1的HTTP版本。第二行开始是HTTP的请求头部。除了GET请求外,另一种常用的请求是POST。用浏览器发POST请求稍麻烦,我们就借用curl工具来发送个HTTP POST请求给服务器看下数据又会是怎们样的:curl -d "message=nice to meet you" 127.0.0.1:9734/hello

服务器收到的信息:

C语言编写Http服务器中Request的解析,让一些从零开始

可以看到头部信息之后多了一空行和之后的POST的body数据信息。还要注意的是Content-Length头,代表POST的body数据的大小。

解析 request 的 method url version

先来解析最简单的第一行: "POST /hell HTTP/1.1", 只需要用空格split出三个字符串就好了。

1.request.h

C语言编写Http服务器中Request的解析,让一些从零开始

2.request.c

C语言编写Http服务器中Request的解析,让一些从零开始

3.编写测试用例

C语言编写Http服务器中Request的解析,让一些从零开始

在test目录下执行:` gcc ../request.h ../request.c requestTest.c && ./a.out`,可以看到我们解析的方法正确。

解析 header

header的解析看起来比较复杂,每一行很容易看出是用":"分割的key-value对,所以我们可以用HashMap来表达。如何判断header数据的结束呢,通过前面的观察,可以发现如果是POST会有一个空行和body隔开,是GET的话只能检查客户端的数据是否发完,发完就代表header也结尾了。在正式解析header之前,我们先构造基本数据的数据结构,以方便以后使用。

  • 1. 创建链表结构体
  • 2. 创建哈希表结构体
  • 3. 按行解析header,遇到空行或字符串结尾停止

因为代码比较多,这里不久不把两种结构体得实现代码贴出来,如果足下需要可以私信我"代码"获取。

解析header代码,有了哈希结构体后,解析header就方便多了,只要按行根据":" 拆分成 key和value就行了

关键代码:

C语言编写Http服务器中Request的解析,让一些从零开始

解析body

解析body很简单,如果最后一行不是空格不是空行,说明是有body数据的,空行后面的就是body数据了.

header里面有个关键的key, ‘Content-Length’ 代表了body有多长,我们可以利用这个字段来判断body的结尾。

C语言编写Http服务器中Request的解析,让一些从零开始

大功告成 最后打印我们的成果

打印解析内容

C语言编写Http服务器中Request的解析,让一些从零开始

执行 gcc request.h request.c main.c tools/utils.c tools/utils.h && ./a.out

然后新开一个终端执行 curl -d "message=nice to meet you" 127.0.0.1:9734/hello-everyone

看到输出结果:

C语言编写Http服务器中Request的解析,让一些从零开始

总的来说难度系数还是有一些得呦,再见。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Learning PHP 5

Learning PHP 5

David Sklar / O'Reilly / July, 2004 / $29.95

Learning PHP 5 is the ideal tutorial for graphic designers, bloggers, and other web crafters who want a thorough but non-intimidating way to understand the code that makes web sites dynamic. The book ......一起来看看 《Learning PHP 5》 这本书的介绍吧!

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具