HTTP协议介绍

http协议

  • http协议是应用层协议,一般建立在tcp协议的基础之上(当然你的实现非要基于udp也是可以的),也就是说http协议的数据收发是通过tcp协议的。

  • http协议也分为head和body两部分,但是我们一般说的html中的和标记不是http协议的头和身体,它们都是http协议的body部分。

http协议格式

请求报文:

GET或POST 请求的url路径(一般是去掉域名的路径) HTTP协议版本号\r\n
字段1名: 字段1值\r\n
字段2名: 字段2值\r\n
…
字段n名 : 字段n值\r\n
\r\n
http协议包体内容

也就是说http协议由两部分组成:包头和包体,包头与包体之间使用一个\r\n分割,由于http协议包头的每一行都是以**\r\n结束,所以http协议包头一般以\r\n\r\n**结束。

响应报文:

GET或POST 响应码 HTTP协议版本号\r\n
字段1名: 字段1值\r\n
字段2名: 字段2值\r\n
     …
字段n名 : 字段n值\r\n
\r\n
http协议包体内容

GET请求

举个例子,比如我们在浏览器中请求 http://www.archforce.cn/ 这个网址,这是一个典型的GET方法,浏览器组装的http数据包格式如下:

GET / HTTP/1.1
Host: www.archforce.cn
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.162 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: Hm_lvt_cbf861d48d9cddec571cd12e72a1609f=1625847951; Hm_lpvt_cbf861d48d9cddec571cd12e72a1609f=1625848189
If-None-Match: "3e05c-KllfhaoJ3NEVgn4MeRRVM0morj0"

Request请求

回应包

HTTP/1.1 304 OK
Server: nginx/1.12.2
Date: Fri, 09 Jul 2021 16:31:12 GMT
Connection: keep-alive

response请求
如果GET请求带参数,那么一般是附加在请求的url后面,参数与参数之间使用&分割,例如请求http://www.archforce.cn/?param1=value1&param2=value2&param3=value3,我们看下这个请求组装的的http协议包格式:

GET /?param1=value1&param2=value2&param3=value3 HTTP/1.1
Host: www.archforce.cn
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.162 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: Hm_lvt_cbf861d48d9cddec571cd12e72a1609f=1625847951; Hm_lpvt_cbf861d48d9cddec571cd12e72a1609f=1625849203
If-None-Match: "3dfe9-2kN4Gmh10x7woA+VHkm336SXibw"

请求响应包格式:

HTTP/1.1 304 OK
Server: nginx/1.12.2
Date: Fri, 09 Jul 2021 16:53:35 GMT
Connection: keep-alive

POST请求

当用户发请HTTP POST请求时,POST的数据放在什么位置呢?

我们在12306网站 http://www.4399.com/ 中登陆输入用户名和密码:

用户:binbin_erices@163.com
密码:123456

Wireshark设置http.request.method==POST 过滤POST请求

POST /ptlogin/login.do?v=1 HTTP/1.1
Host: ptlogin.4399.com
Connection: keep-alive
Content-Length: 492
Cache-Control: max-age=0
Origin: http://ptlogin.4399.com
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.162 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://ptlogin.4399.com/ptlogin/loginFrame.do?postLoginHandler=default&redirectUrl=&displayMode=popup&css=&bizId=&appId=www_home&gameId=&username=&externalLogin=qq&password=&mainDivId=popup_login_div&autoLogin=false&includeFcmInfo=false&qrLogin=true&userNameLabel=4399%E7%94%A8%E6%88%B7%E5%90%8D&userNameTip=%E8%AF%B7%E8%BE%93%E5%85%A54399%E7%94%A8%E6%88%B7%E5%90%8D&welcomeTip=%E6%AC%A2%E8%BF%8E%E5%9B%9E%E5%88%B04399&level=0&regLevel=4&v=1625851237354
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: home4399=yes; UM_distinctid=17a8c4907acb-03fd12d521e1a9-4313f6f-100200-17a8c4907ad800; Hm_lvt_334aca66d28b3b338a76075366b2b9e8=1625851234; Hm_lpvt_334aca66d28b3b338a76075366b2b9e8=1625851234; _gprp_c=""; USESSIONID=e01ffc99-af9b-49d3-96a8-ed25addc20d1

loginFrom=uframe&postLoginHandler=default&layoutSelfAdapting=true&externalLogin=qq&displayMode=popup&layout=vertical&bizId=&appId=www_home&gameId=&css=&redirectUrl=&sessionId=&mainDivId=popup_login_div&includeFcmInfo=false&level=0&regLevel=4&userNameLabel=4399%E7%94%A8%E6%88%B7%E5%90%8D&userNameTip=%E8%AF%B7%E8%BE%93%E5%85%A54399%E7%94%A8%E6%88%B7%E5%90%8D&welcomeTip=%E6%AC%A2%E8%BF%8E%E5%9B%9E%E5%88%B04399&sec=1&password=U2FsdGVkX19Ch0%2FiMqtxiFo3gEmqd46gG5kYggkMI%2Bg%3D&username=binbin_erices%40163.com

其中password=U2FsdGVkX1%2BxNjF6YOTUt%2B0QbDEgoeWtonbF3bbVZqA%3D&username=erices

就是我们的POST数据,但是大家需要注意的以下几种,不要搞错:

  • 我的用户名是binbin_erices@163.com,到POST里面变成binbin_erices%40163.com,其中%40是@符号的16进制转码形式。这个码表可以参考这里:》 http://www.w3school.com.cn/tags/html_ref_urlencode.html

这里有多个变量,他们之间使用&符号分割,但是请注意的是,这不意味着传递多个POST变量时必须使用&符号分割,只不过这里是浏览器html表单(输入用户名和密码的文本框是html表单的一种)分割多个变量采用的默认方式而已。你可以根据你的需求,来自由定制,只要让服务器知道你的解析方式即可。

http客户端实现

如果掌握以上说的http协议,你就可以自己通过代码组装http协议发送http请求了(也是各种开源http库的做法)。我们先简单地介绍一下如何模拟发送http。举个例子,我们要请求 http://www.baidu.com/,那么我们可以先通过域名得到ip地址,即通过socket API gethostbyname()得到http://www.baidu.com/的ip地址,由于http服务器默认的端口号是80,有了域名和ip地址之后,我们使用socket API connect()去连接服务器,然后根据上面介绍的格式组装成http协议包,利用socket API send()函数发出去,如果服务器有应答,我们可以使用socket API recv()去接受数据,接下来就是解析数据(先解析包头和包体)。

开源HTTPRequest库

  • 27
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Erice_s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值