当前位置: 首页 > 科技观察

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

时间:2023-03-17 15:35:44 科技观察

制作过程观察接收到的http数据,分析request的方法url版本,分析header,分析body,观察接收到的http数据如果你能完成一个简单的基于TCP/IP的套接字服务器程序,那么恭喜你,你可以仔细阅读这篇文章。HTTP在形式上是基于TCP/IP应用层协议的,所以只要我们的程序能够理解HTTP数据并做出符合HTTP协议的响应,那么就可以完成HTTP通信。如果你有机会,使用常识来远程登录到我们的服务器,你会得到无意义的字符。如果是浏览器,会发送什么?我们尝试在浏览器地址栏输入我们的服务器地址:127.0.0.1:9734进行访问,发现浏览器提示“127.0.0.1发送的响应无效。”,也就是说我们返回的数据browser无法被浏览器读取,因为现代浏览器默认使用http协议请求访问我们的服务器,而我们返回的数据只是“helloworld”字符串,不符合http协议的返回格式。尽管如此,浏览器还是很诚恳的向我们的服务器发送了一个标准的http请求。不信我们看一下我们服务器收到的信息:先观察一会,好像***行是http请求的类型,第二行开始是一些键值对分隔经过”:”。确实,***行告诉我们,我们使用的是GET请求,请求的url是“/”,使用的HTTP版本是1.1。第二行以HTTP请求标头开头。除了GET请求,另一个常用的请求是POST。用浏览器发送POST请求有点麻烦,所以我们使用curl工具向服务器发送HTTPPOST请求,看看数据会是什么样子:curl-d"message=nicetomeetyou"127.0.0.1:9734/hello服务器收到的信息:可以看到header信息后面有一个空行,后面是POST的body数据信息。另请注意,Content-Length标头表示POST正文数据的大小。解析请求的方法url版本先来解析最简单的***行:“POST/hellHTTP/1.1”,只需要用空格分割三个字符串即可。1.请求.h2.请求.c3。写一个测试用例,在测试目录下执行:`gcc../request.h../request.crequestTest.c&&./a.out`,可以看到我们解析的方法是正确的。解析headerheader的解析看起来比较复杂,每一行很容易看出是一个用“:”分隔的键值对,所以我们可以用HashMap来表示。如何判断头数据结束?通过前面的观察,我们可以发现,如果是POST的话,会和body隔开一个空行。如果是GET,我们只能检查客户端的数据是否已经发送。发送完,也就意味着header也结束了。在正式解析header之前,我们先构建基础数据的数据结构,以备后用。1.创建一个链表结构。2.创建哈希表结构。3.逐行解析标题。遇到空行或字符串结尾时停止,因为代码很多。两种结构的实现代码我就不贴在这里了。需要的可以私信我“code”获取。解析头代码。有了hash结构,解析header就方便多了。只需按照":"逐行拆分成key和value即可Key代码:解析body很简单,如果***行不是空格不是空行,说明有body数据,body数据在空行后面。header中有一个key,'Content-Length'表示body有多长,我们可以通过这个字段来判断body结束。大功告成***打印我们的结果打印解析后的内容执行gccrequest.hrequest.cmain.ctools/utils.ctools/utils.h&&./a.out然后打开一个新终端执行curl-d"message=nicetomeetyou"127.0.0.1:9734/hello-everyone查看输出:总体来说,难度系数还是有点不错的,再见。