TCP模拟HTTP请求

article/2025/10/2 10:26:03

HTTP的特性

  • HTTP是构建于TCP/IP协议之上,是应用层协议,默认端口号80

  • HTTP协议是无连接无状态的

HTTP报文

请求报文

HTTP协议是以ASCⅡ码传输,建立在TCP/IP协议之上的应用层规范。

HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,下图是请求报文的一般格式。

1、请求行

请求行是由请求方法、url字段以及HTTP协议版本字段三个部分组成,它们用空格分开。

HTTP协议的请求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。

而常见的有如下几种:

1.1 GET

当客户端要从服务器读取数据时,点击网页上的链接,或者通过在浏览器的地址栏输入网址来浏览网页的,使用的都是GET方式。GET的方法要求服务器将URL定位的资源放在响应报文的数据部分,回送给客户端。使用GET的方法,请求参数和对应的值附加在URL后面,利用问号 (?),代表URL的结尾和请求参数的开始,传递的参数长度受到限制。例如,/index.html?id=1&password=123,这样通过GET的方式传递的数据直接显示在地址上,所以我们可以将请求以链接的方式发送给接收方。以http://httpbin.org/get为例,request的格式如下:

可以看到GET的请求一般不包含“请求内容”的部分,请求数据以地址的形式表现在请求行中,地址 ? 之后的部分就是通过GET发送的数据,我们可以在地址栏中看到各种数据之间用 & 符号隔开。

  • 但是这种方式显然不能传递私密的数据。

  • 另外不同浏览器对地址的字符长度限制有不同的数据,一般最多不超过1024个字符,所以大量的数据传输,不适合使用GET方式。

1.2 POST

对于以上适合使用GET方式的情况下,可以使用POST方式,因为使用POST的方法允许客户端给服务端提供较多的信息。POST将请求参数封装在HTTP的请求数据中,可以大量的传递数据,理论上对数据得大小的没有限制,但实际各个WEB服务器会规定对post提交数据大小进行限制。而且可以不显示在URL中。下图是用wireshark抓的一个POST请求的报文,红色为请求报文,蓝色为响应报文

可以看到POST方式的请求行中不包括字符串数据,这些内容保存在“请求内容”部分,各个数据之间也是以 & 符号隔开。

POST方法向服务器提交数据,比如表单的数据的提交。GET的方法一般用于获取/查询资源信息。

2、请求头部

请求头部由键值对组成,关键字和值之间用 : 分开。请求头封装了有关客户端请求的信息,典型的请求头有:

请求头

含义

User-Agent

产生请求的浏览器类型,User-Agent请求报头域允许客户端将它的操作系统、浏览器和其它属性告诉服务器

Accept

客户端可识别的响应内容类型列表。eg:Accept:image/gif,表明客户端希望接受GIF图象格式的资源;Accept:text/html,表明客户端希望接受html文本。

Accept-Language

客户端可接受的自然语言

Accept-chartset

客户端可接受应答的字符集。eg:Accept-Charset:iso-8859-1,gb2312.如果在请求消息中没有设置这个域,缺省是任何字符集都可以接受。

Accept-Encoding

客户端可接受的编码压缩格式

HOST

请求的主机名称,允许多个域名同处一个IP之地,即虚拟主机

Connection

连接方式(close或keep-alive)

Cookie

存储于客户端扩展字段,向同一域名的服务端发送该域的cookie

Authorization

Authorization请求报头域主要用于证明客户端有权查看某个资源。当浏览器访问一个页面时,如果收到服务器的响应代码为401(未授权),可以发送一个包含Authorization请求报头域的请求,要求服务器对其进行验证。

3、空行

最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不会再有请求头。

4、请求数据

请求数据不再GET方法中使用,而是在POST方法中使用。POST方法适用于客户端提交表单。与请求数据相关的最常使用的请求头是包体类型 Content-Type 和包体长度 Content-Length

代码:

import sockettcp_socket_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcp_socket_client.connect(("httpbin.org", 80))request_head = "GET /get HTTP/1.1\r\n"request_headers = "Host: httpbin.org\r\nConnection:close\r\n"request_end = "\r\n"request = request_head + request_headers + request_endtcp_socket_client.send(request.encode("utf-8"))datas_bytes = b""while True:data = tcp_socket_client.recv(1024)if not data:breakdatas_bytes += datacontent = datas_bytes.decode("utf-8")print(content)
response_head = content.split("\r\n")[0]
response_headers = content.replace(response_head + "\r\n", "").split("\r\n")
index = response_headers.index("")
print(index)headers = "\r\n".join(response_headers[:index])
print(headers)data = "\r\n".join(response_headers[index+1:])
print(data)

响应报文

HTTP响应报文是由状态行、响应头部、空行和响应包体四个部分组成,如下图所示

这响应中状态行(status line)代替了请求行。状态行通过提供一个状态码来说明请求情况。

1、状态行

状态行由HTTP协议版本(HTTP-Version),状态码(Statue-Code) 和 状态码描述文本(Reason-Phrase) 三个部分组成,它们之间用空格隔开;

状态码有三位数字组成,第一位定义了响应的类别,可能有五种取值:

  • 1xx:表示服务端已经接收到客户端请求,客户端可以继续发送请求;

  • 2xx:表示服务端已经成功接收请求并处理;

  • 3xx:表示服务器要求客户端重定向;

  • 4xx:客户端请求有问题;

  • 5xx:服务端未能正常处理客户端的请求出现错误;

常见状态码描述文本有如下:

  • 200 OK:请求成功;

  • 400 Bad Request:客户端请求语法有问题,不能被服务端理解;

  • 401 Unauthorized:请求未经授权,必须与Authorization请求报头域一起使用(eg:BASE64用户身份验证);

  • 403 Forbidden:服务器收到请求但是拒绝提供服务,通常会在响应正文中给出不提供服务的原因;

  • 404 Not Found:请求的资源不存在,eg,输错了URL;

  • 500 Internal Server Error:服务器发生错误,无法完成客户端请求;

  • 503 Service Unavailable:表示服务器当前不能处理客户端请求,一段时间之后可能恢复正常;

2、响应头

响应头可能包括以下信息:

响应头

描述

Server

Server 响应报头域包含了服务器用来处理请求的软件信息及其版本。它和 User-Agent 请求报头域是相对应的,前者发送服务器端软件的信息,后者发送客户端软件(浏览器)和操作系统的信息。

Vary

指示不可缓存的请求头列表

Connection

连接方式

www-Authenticate

WWW-Authenticate响应报头域必须被包含在401 (未授权的)响应消息中,这个报头域和前面讲到的Authorization 请求报头域是相关的,当客户端收到 401 响应消息,就要决定是否请求服务器对其进行验证。如果要求服务器对其进行验证,就可以发送一个包含了Authorization 报头域的请求

3、响应包体

服务器返回给客户端的文本信息

以下是用wireshark抓的一段响应报文

HTTP无状态性

HTTP协议是无状态的(stateless)。也就是说,同一个客户端第二次访问同一个服务器上面的页面时,服务器无法得知这个客户端曾经访问过,服务器无法辨别不同的客户端。HTTP的无状态性简化了服务器的设计,是服务器更容易支持大量并发的HTTP请求。

HTTP协议是采用请求-响应的模型。客户端向服务端发送一个请求报文,服务端以一个状态作为回应。

当使用普通模式,即非keep-alive模式时,每个请求-应答都要重新建立一个连接,连接完成后立即断开;

HTTP1.1 使用持久连接keep-alive,所谓持久连接,就是服务器在发送响应后仍然在一段时间内保持这条连接,允许在同一个连接中存在多次数据请求和响应,即在持久连接情况下,服务器在发送完响应后并不关闭TCP 连接,而客户端可以通过这个连接继续请求其他对象。

HTTP 长连接不可能一直保持,例如 Keep-Alive: timeout=5, max=100,表示这个TCP通道可以保持5秒,max=100,表示这个长连接最多接收100次请求就断开。

HTTP 是一个无状态协议,这意味着每个请求都是独立的,Keep-Alive 没能改变这个结果。另外,Keep-Alive也不能保证客户端和服务器之间的连接一定是活跃的,在 HTTP1.1 版本中也如此。唯一能保证的就是当连接被关闭时你能得到一个通知,所以不应该让程序依赖于 Keep-Alive 的保持连接特性,否则会有意想不到的后果。

浏览器控制台中的http报文

这里简单的放一张浏览器控制台的http请求报文解析

代码:

import sockettcp_socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcp_socket_server.bind(("0.0.0.0", 8080))
tcp_socket_server.listen(1024)tcp_socket_c, tcp_socket_info = tcp_socket_server.accept()data = tcp_socket_c.recv(10240)print(data.decode("utf-8"))response_head = "HTTP/1.1 200 OK\r\n"
response_headers = "Content-Type: text/html; charset=utf-8\r\nServer: gunicorn/19.9.0\r\n"
response_space = "\r\n"
response_content = """
{"args": {}, "headers": {"Accept": "application/json", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9", "Host": "httpbin.org", "Referer": "http://httpbin.org/", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36", "X-Amzn-Trace-Id": "Root=1-6405c3a3-29198e8b33a7a9ea54a2afca"}, "origin": "120.244.162.239", "url": "http://httpbin.org/get"
}"""response_data = response_head + response_headers + response_space + response_content
tcp_socket_c.send(response_data.encode("utf-8"))
tcp_socket_c.close()
tcp_socket_server.close()

http://chatgpt.dhexx.cn/article/rtM47YeR.shtml

相关文章

使用postman模拟post、get请求

postman通常作为一种接口测试工具,如:采用post、get等方式,模拟对接口进行访问,用于查看接口功能是否正常。 模拟POST请求 选择请求方式为POST 设置请求url地址 http://localhost:8081/webside/subSystemLogin.html 选择Header…

如何简单的模拟发送http post请求

有天在做项目演示的时候要用到post请求的模拟发送,为此总不至于写一个html页面,当时只记得百度了一下模拟发送http post请求,方法大概都是说用fiddler工具或者使用cmd内置telnet客户端模拟http请求。 这里抄送附上fiddler工具和telnet模拟po…

接口测试中模拟post四种请求数据

转自 作者:隋胖胖LoveFat 链接:https://www.jianshu.com/p/3b6d7aa2043a 来源:简书 一、背景介绍 在日常的接口测试工作中,模拟接口请求通常有两种方法,fiddler模拟和HttpClient模拟。 Fiddler是一个简单的http协议调…

谷歌学术访问

https://via.hypothes.is/ 不需要镜像,不需要任何操作,只需打开这个网站,输入你要访问的学术网站,秒开 第一步: 第二步:

谷歌学术(google scholar)个人主页的论文信息不准确怎么办?

题目:谷歌学术(google scholar)个人主页的论文信息不准确怎么办? 谷歌学术主页是很多人展示自己学术成果的一种方式,但很多时候,谷歌自动给你聚集到主页的论文信息是有误的,这时候怎么去编辑呢? 论文信息…

谷歌学术介绍

转载自:http://blog.renren.com/share/111541487/15517062888 “谷歌学术”是谷歌搜索引擎中的学术检索部分,相对于知网、维普、万方、Pubmed等专业的论文数据库来说功能单薄了些,但具有页面简约、搜索速度快、集国内外文献于一体、某些文章可…

Google 学术搜索(Google Scholar)使用技巧

本文简介Google 学术搜索(Google Scholar)使用技巧, 关于Web Of Science 上搜索文献,查看SCI分区及影响因子情况参见我的另一篇博客(https://xiongyiming.blog.csdn.net/article/details/78474211) Google…

【谷歌学术】使用指南

【谷歌学术】使用指南 谷歌可以清楚看到作者的影响力,尤其是在衡量一个学者有多厉害,论文质量有多高【往往是博士阶层往上】 谷歌学术网站: https://scholar.google.com.hk/?hlzh-CN 查人 查论文都很好用 同时你订阅这个作者 还会收到他…

如何在谷歌学术下载论文

如何在谷歌学术下载论文(在Mac Pro上记录,但是windows应该同样适用) 1 下载谷歌浏览器 下载谷歌浏览器 官网截图如下: 2 下载谷歌浏览器扩展程序 googlehelper下载 在下载的时候,要记住下载的位置,后面…

谷歌学术搜索

Google Scholar (谷歌学术搜索,简称GS)是一个可以免费搜索学术文章的网络搜索引擎索引了出版文章中文字的格式和科目,能够帮助用户查找包括期刊论文、学位论文、书籍、预印本、文摘和技术报告在内的学术文献,内容涵盖自…

谷歌学术Google Scholar超实用干货(拒绝翻墙/插件)

最近看了很多大佬博主发的谷歌学术使用总结,觉得特别有用,小P在这里简单的总结一下,给自己做个使用大纲,也分享给大家啦!(觉得有帮助别忘了点赞、收藏哦) 谷歌学术简单来说就是一个汇集大量外文文献的网站(类似于百度学术)。百度学术的特点是:精简、不全不新,谷歌学…

科研——谷歌学术使用方法

输入需要搜索的文章名 点击“引用”,即可以出此篇文章的引用格式。点击“被引用次数”,即可以看到引用此篇文章的其他文章。 勾选“在引用文章中搜索”,在上方的空白处,搜索这些引用文章中的具体文章。 点击一篇查看是否被真正引用…

谷歌学术——下载论文

一些同学在找论文的时候,在学校数据库找不到,因此可以使用谷歌学术来找。但是国内被墙了,无法访问,所以可以使用镜像服务器。 首先进入谷歌镜像: 镜像网站(https://ac.scmor.com/) 点击进入之后…

国内外常用学术网站(访问不了“谷歌学术”的,试一试有惊喜哦)

搞学术的可能对如何能够快速查找优质免费学术资源感到头大于是笔者寻找了许许多多方法,搜集了很多网站,期望谷歌访问不了是可以找到替代或者与谷歌学术相媲美的网站,现汇总如下分享给大家,希望对搞研究的有所帮助。 一、学术网站…

RPC框架介绍

什么是RPC框架: 远程过程调用RPC,就是客户端基于某种传输协议通过网络向服务提供端请求服务处理,然后获取返回数据(对于ONE WAY模式则不返还响应结果);而这种调用对于客户端而言,和调用本地服务一样方便,开…

跨语言rpc框架Thrift

RPC 全称 Remote Procedure Call——远程过程调用。RPC技术简单说就是为了解决远程调用服务 的一种技术,使得调用者像调用本地服务一样方便透明 Thrift的定义 Thrift是一个轻量级、跨语言的RPC框架,主要用于各个服务之间的RPC通信,最初由Face…

RPC 框架性能大比拼

Dubbo 是阿里巴巴公司开源的一个Java高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。 Motan 是新浪微博开源的一个Java 框架。它诞生的比较晚,起于2013年,2016年5月开源。Motan 在微博平台中已经广泛应用,每天为数…

分布式RPC框架性能大比拼

点击上方“后端技术精选”,选择“置顶公众号” 技术文章第一时间送达! 来源:鸟窝 链接:http://985.so/aXe2 推荐阅读(点击即可跳转阅读) 1. SpringBoot内容聚合 2. 面试题内容聚合 3. 设计模式内容聚合 4. 排序算法内容聚合 5. 多…

C++微服务RPC框架,一文带你彻底搞懂 RPC

RPC(Remote Procedure Call),是一个大家既熟悉又陌生的词,只要涉及到通信,必然需要某种网络协议。我们很可能用过HTTP,那么RPC又和HTTP有什么区别呢?RPC还有什么特点,常见的选型有哪…

手动实现一个RPC框架 (一):RPC的介绍

手动实现RPC框架 最近在备战22年暑假实习的招聘,由于之前也没有实习的经验,所以在项目经验这方面也比较缺乏。在跟着B站尚硅谷的课程学习完微服务和分布式组件的内容后又跟着写了尚医通的微服务实战项目。尚医通项目中有使用到OpenFeign和FeignClient来远…