当前位置: 首页 > news >正文

通过 Socket 手动实现 HTTP 协议

你好,我是 shengjk1,多年大厂经验,努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注!你会有如下收益:

  1. 了解大厂经验
  2. 拥有和大厂相匹配的技术等

希望看什么,评论或者私信告诉我!

文章目录

  • 一、前言
  • 二、 定义 socket server
  • 三、分析客户端请求参数-GET请求
  • 四、分析客户端请求参数-PUT请求
  • 五、服务端响应参数
  • 六、扩展
    • 6.1 content-type
  • 七、总结


一、前言

上一篇中,我们详细 HTTP 协议的基本原理到请求与响应的详细结构,并且提供了丰富的信息和实用的例子。为了更进一步了解 HTTP 协议,于是有了这篇文章

二、 定义 socket server

本文我们通过 Socket,写一个 HTTP 协议,直观的感受一下上篇文章中的请求和响应。
通过上篇文章,我们知道 HTTP 协议底层是通过 Socket 实现的,所以我们先通过 socket 定义一个 server


import socket#初始化 socke
sock=socket.socket()
#绑定 地址
sock.bind(('127.0.0.1',8081))#在 sock.listen(5) 中,参数 5 表示最多可以排队等待处理的连接数量为 5。
# 如果有更多的连接请求到达,超过该数量的连接将被拒绝。
sock.listen(5)
while True:#接受客户端请求conn,addr=sock.accept()data=conn.recv(1024)print('客户端的请求数据\r\n',data.decode('utf-8'))print("打印完毕=====")#响应客户端的请求conn.send(b'Hello world')conn.close()

在 PyCharm 中执行这段代码后,通过浏览器访问 http://127.0.0.1:8081/
Sever 端 PyCharm 打印结果

客户端的请求数据
GET / HTTP/1.1
Host: 127.0.0.1:8081
Connection: keep-alive
sec-ch-ua: "Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7打印完毕=====

三、分析客户端请求参数-GET请求

在上篇文章中我们讲到 HTTP 协议在发送请求的时候,必须要包含请求行、请求头、请求体。这是浏览器帮我们组织好的。
此处的请求行为

GET / HTTP/1.1

请求头为:

Host: 127.0.0.1:8081
Connection: keep-alive
sec-ch-ua: "Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7

请求体为:

之所以为空,是因为 GET 请求没有请求体。

四、分析客户端请求参数-PUT请求

首先通过 python request 包发送 put 请求,因为请求必须要包括请求行、请求头以及请求体,所以 python request 模板会帮我们组织好。

import requestsdata={"username":"test","password":"<PASSWORD>"}
respone=requests.post("http://127.0.0.1:8081",json=data)
print(respone)

Sever 端 PyCharm打印结果

客户端的请求数据
POST / HTTP/1.1
Host: 127.0.0.1:8081
User-Agent: python-requests/2.31.0
Accept-Encoding: gzip, deflate, br, zstd
Accept: */*
Connection: keep-alive
Content-Length: 46
Content-Type: application/json{"username": "test", "password": "<PASSWORD>"}
打印完毕=====

此处的请求行为:

POST / HTTP/1.1

请求头为:

Host: 127.0.0.1:8081
User-Agent: python-requests/2.31.0
Accept-Encoding: gzip, deflate, br, zstd
Accept: */*
Connection: keep-alive
Content-Length: 46
Content-Type: application/json

请求体为:

{"username": "test", "password": "<PASSWORD>"}

五、服务端响应参数

通过浏览器访问 http://127.0.0.1:8081/ 时,虽然 server 端接受到请求了,也给浏览器反回了 hello world 但浏览器仍然报错了

另外当我们通过 python request 发送 put 请求时,同样 server 端接受到请求了,也返回了 hello world 但 request 程序仍然报错了

Traceback (most recent call last):File "/Users/isx/opt/anaconda3/lib/python3.11/site-packages/urllib3/connectionpool.py", line 791, in urlopenresponse = self._make_request(^^^^^^^^^^^^^^^^^^^File "/Users/isx/opt/anaconda3/lib/python3.11/site-packages/urllib3/connectionpool.py", line 537, in _make_requestresponse = conn.getresponse()^^^^^^^^^^^^^^^^^^File "/Users/isx/opt/anaconda3/lib/python3.11/site-packages/urllib3/connection.py", line 461, in getresponsehttplib_response = super().getresponse()^^^^^^^^^^^^^^^^^^^^^File "/Users/isx/opt/anaconda3/lib/python3.11/http/client.py", line 1390, in getresponseresponse.begin()File "/Users/isx/opt/anaconda3/lib/python3.11/http/client.py", line 325, in beginversion, status, reason = self._read_status()^^^^^^^^^^^^^^^^^^^File "/Users/isx/opt/anaconda3/lib/python3.11/http/client.py", line 307, in _read_statusraise BadStatusLine(line)
http.client.BadStatusLine: Hello world

这是为什么?
上篇文章中,我们也讲过,服务端的响应也必须要包括响应行、响应头以及响应体,而我们写的 sever 中代码,赵括响应体,所以浏览器和 python request 包会报错。

#响应客户端的请求
conn.send(b'Hello world') 

我们遵循服务端的响应也必须要包括响应行、响应头以及响应体这个要求,改进 server 代码

import socketsock=socket.socket()sock.bind(('127.0.0.1',8081))
#在 sock.listen(5) 中,参数 5 表示最多可以排队等待处理的连接数量为 5。
# 如果有更多的连接请求到达,超过该数量的连接将被拒绝。
sock.listen(5)
while True:conn,addr=sock.accept()data=conn.recv(1024)print('客户端的请求数据\r\n',data.decode('utf-8'))print("打印完毕=====")conn.send(b'HTTP/1.1 200 OK \r\nDate: Tue, 02 Mar 2024 12:00:00 GMT\r\nServer: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips\r\nContent-Type: text/plain\r\nHello world')conn.close()

六、扩展

6.1 content-type

content-type 是请求头以及响应头中最重要的参数,它可以分别告诉客户端和服务端该如何处理请求体或者响应体中的参数。举个例子:
server代码

import socketsock=socket.socket()sock.bind(('127.0.0.1',8081))
#在 sock.listen(5) 中,参数 5 表示最多可以排队等待处理的连接数量为 5。
# 如果有更多的连接请求到达,超过该数量的连接将被拒绝。
sock.listen(5)
while True:conn,addr=sock.accept()data=conn.recv(1024)print('客户端的请求数据\r\n',data.decode('utf-8'))print("打印完毕=====")conn.send(b'HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n{"username": "test", "password": "<PASSWORD>"}')conn.close()

为了更好的呈现响应的结果,这个我们借助 postman 工具。当 Content-Type: text/plain,postman 接受服务端返回的数据类型为 text

当 Content-Type:application/json 时,postman 服务端返回的数据类型为 json

七、总结

本文通过实际代码和请求示例,深入探讨了HTTP协议的实现和交互过程。通过对Socket的使用,读者能够更直观地理解HTTP请求和响应的过程。同时,文章强调了请求和响应中的参数组成,以及服务端响应中的必要元素。最后,通过content-type的讨论,读者能够更好地理解数据类型对于请求和响应的影响。

相关文章:

通过 Socket 手动实现 HTTP 协议

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…...

探索数据结构:双向链表的灵活优势

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;数据结构与算法 贝蒂的主页&#xff1a;Betty’s blog 1. 前言 前面我们学习了单链表&#xff0c;它解决了顺序表中插入删除需…...

记录一次服务器内存使用率过高达到90%告警问题排查。

目录 一、前言二、问题排查处理三、 结尾 &#x1f469;&#x1f3fd;‍&#x1f4bb;个人主页&#xff1a;阿木木AEcru &#x1f525; 系列专栏&#xff1a;Docker容器化部署系列 &#x1f4b9;每一次技术突破&#xff0c;都是对自我能力的挑战和超越。 一、前言 一大早就有一…...

基于react native的自定义轮播图

基于react native的自定义轮播图 效果示例图示例代码 效果示例图 示例代码 import React, {useEffect, useRef, useState} from react; import {Animated,PanResponder,StyleSheet,Text,View,Dimensions, } from react-native; import {pxToPd} from ../../common/js/device;c…...

Jetson入坑记实

关于虚拟环境python与系统自带python目录下dist-packages与site-packages dist-packages&#xff1a;系统自带的python site-packages&#xff1a;自己安装的python 详细&#xff1a;dist-packages与site-packages_dist-packages和site-packages-CSDN博客 rtsp获取视频流(没…...

算法系列--递归

一.如何理解递归 递归对于初学者来说是一个非常抽象的概念,笔者在第一次学习时也是迷迷糊糊的(二叉树遍历),递归的代码看起来非常的简洁,优美,但是如何想出来递归的思路或者为什么能用递归这是初学者很难分析出来的 笔者在学习的过程中通过刷题,也总结出自己的一些经验,总结来…...

【JS】替换文本为emjio表情

最终效果展示 T1 T2 T3 T4 需求 把评论你好帅啊啊啊[开心][开心]&#xff0c;[开心] 替换为图片 思路 正则match提取[开心]到一个数组数组去重创建img标签img标签转文本. 。例&#xff1a;&#xff08;el.outerHTML&#xff09;&#xff0c;将el元素转文本字符串replaceAll…...

Solr完结版

Solr是基于Apache Lucene构建的用于搜索和分析的开源解决方案。提供可拓展索引、搜索功能、高亮显示和文字解析功能。本质是一个java web项目&#xff0c;内嵌Jetty服务器&#xff0c;安装方便。 请求Solr中的控制器&#xff0c;处理完数据后把结果相应给客户端 正向索引&#…...

外包干了5天,技术退步明显。。。。

说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入广州某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&a…...

Cronos zkEVM 基于 Covalent Network(CQT)数据可用性 API,推动其 Layer2 DeFi 生态更好地发展

在一项旨在显著改善 DeFi 生态的战略举措中&#xff0c;Cronos 与 Covalent Network&#xff08;CQT&#xff09;携手合作&#xff0c;以期待 Cronos zkEVM 的推出。这一整合&#xff0c;预计将进一步降低以太坊生态系统的交易成本、提升交易速度&#xff0c;并带来更好的交易体…...

基于SpringBoot的高校办公室行政事务管理系统

采用技术 基于SpringBoot的高校办公室行政事务管理系统的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBootMyBatis 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 页面展示效果 功能清单 教师信息管理 办公室管理 办公物资管…...

Linux系统及操作 (04)

Linux系统及操作 (03) RPM 软件包 网络下载对应软件包光盘镜像文件&#xff0c;具备软件包 Windows 系统软件包的管理 可以指定安装位置安装是集中安装到一个目录Linux 系统 与 Windows 系统相反。 常见的软件包&#xff08;生态&#xff09;类型 电脑入侵99%都是通过软件…...

粒子群算法 - 目标函数最优解计算

粒子群算法概念 粒子群算法 (particle swarm optimization&#xff0c;PSO) 由 Kennedy 和 Eberhart 在 1995 年提出&#xff0c;该算法模拟鸟群觅食的方法进行寻找最优解。基本思想&#xff1a;人们发现&#xff0c;鸟群觅食的方向由两个因素决定。第一个是自己当初飞过离食物…...

关于MySQL数据库的学习3

目录 前言: 1.DQL&#xff08;数据查询语言): 1..1基本查询&#xff1a; 1.2条件查询&#xff1a; 1.3排序查询&#xff1a; 1.3.1使用ORDER BY子句对查询结果进行排序。 1.3.2可以按一个或多个列进行排序&#xff0c;并指定排序方向&#xff08;升序ASC或降序DESC&#…...

笔试题——得物春招实习

开幕式排练 题目描述 导演在组织进行大运会开幕式的排练&#xff0c;其中一个环节是需要参演人员围成一个环形。演出人员站成了一圈&#xff0c;出于美观度的考虑&#xff0c;导演不希望某一个演员身边的其他人比他低太多或者高太多。 现在给出n个参演人员的身高&#xff0c;问…...

动手做简易版俄罗斯方块

导读&#xff1a;让我们了解如何处理形状的旋转、行的消除以及游戏结束条件等控制因素。 目录 准备工作 游戏设计概述 构建游戏窗口 游戏方块设计 游戏板面设计 游戏控制与逻辑 行消除和计分 判断游戏结束 界面美化和增强体验 看看游戏效果 准备工作 在开始编码之前…...

【极简无废话】open3d可视化torch、numpy点云

建议直接看文档&#xff0c;很多都代码老了&#xff0c;注意把代码版本调整到你使用的open3d的版本&#xff1a; https://www.open3d.org/docs/release/tutorial/visualization/visualization.html 请注意open3d应该已经不支持centos了&#xff01; 从其他格式转换成open3d…...

C语言经典算法-6

文章目录 其他经典例题跳转链接31.数字拆解32.得分排行33.选择、插入、气泡排序34.Shell 排序法 - 改良的插入排序35.Shaker 排序法 - 改良的气泡排序 其他经典例题跳转链接 C语言经典算法-1 1.汉若塔 2. 费式数列 3. 巴斯卡三角形 4. 三色棋 5. 老鼠走迷官&#xff08;一&…...

【计算机考研】杭电 vs 浙工大 怎么选?

想求稳上岸的话&#xff0c;其他几所学校也可以考虑&#xff0c;以留在本地工作的角度考虑&#xff0c;这几所学校都能满足你的需求。 如果之后想谋求一份好工作&#xff0c;肯定优先杭电是比较稳的&#xff0c;当然复习的时候也得加把劲。 这个也可以酌情考虑&#xff0c;报…...

激活函数

优秀的激活函数&#xff1a; 非线性&#xff1a;激活函数非线性时&#xff0c;多层神经网络可逼近所有函数 可微性&#xff1a;梯度下降更新参数 单调性&#xff1a;当激活函数是单调的&#xff0c;能保证单层网络的损失函数是凸函数 近似恒等性&#xff1a;当参数初始化为…...

NBTExplorer终极指南:如何快速掌握6种Minecraft数据格式的图形化编辑

NBTExplorer终极指南&#xff1a;如何快速掌握6种Minecraft数据格式的图形化编辑 【免费下载链接】NBTExplorer A graphical NBT editor for all Minecraft NBT data sources 项目地址: https://gitcode.com/gh_mirrors/nb/NBTExplorer NBTExplorer是一款功能强大且完全…...

别再到处找免费股票数据了!实测可用:Python/JS/Java调用StockAPI获取K线、Level2实时行情保姆级教程

实战指南&#xff1a;用StockAPI高效获取股票数据的多语言解决方案 在金融科技和量化交易领域&#xff0c;获取准确、实时的股票数据是每个开发者面临的第一个挑战。市面上充斥着各种号称"免费"的数据源&#xff0c;但真正稳定可用的却寥寥无几。StockAPI.com.cn作为…...

Hunyuan-MT-7B行业落地:医疗说明书、药品标签民汉双语自动生成

Hunyuan-MT-7B行业落地&#xff1a;医疗说明书、药品标签民汉双语自动生成 在医疗健康领域&#xff0c;信息的准确传递至关重要。无论是药品说明书、医疗器械标签&#xff0c;还是患者教育材料&#xff0c;都需要清晰、无误地传达给不同语言背景的使用者。然而&#xff0c;传统…...

Qwen3-ForcedAligner-0.6B字幕生成:快速上手,本地一键生成视频字幕

Qwen3-ForcedAligner-0.6B字幕生成&#xff1a;快速上手&#xff0c;本地一键生成视频字幕 做视频最头疼的是什么&#xff1f;对我来说&#xff0c;肯定是加字幕。以前要么一个字一个字敲&#xff0c;要么用在线工具&#xff0c;但隐私问题总让人不放心。最近发现一个好东西—…...

STM32高精度定时器(HRTIM1)实现倍频、定时器触发采样

STM32高精度定时器&#xff08;HRTIM1&#xff09;&#xff1a;精准定时与同步触发的强大引擎在嵌入式系统开发中&#xff0c;尤其是在数字电源、电机控制、照明及各类高精度PWM应用领域&#xff0c;定时器的精度和灵活性往往成为系统性能的关键瓶颈。STM32系列微控制器内置的高…...

彻底禁用Windows安全警告弹窗:组策略与命令行的终极指南

1. 为什么Windows总弹出安全警告&#xff1f; 每次双击下载的exe文件时&#xff0c;那个黄底黑字的警告框就像个尽职的保安&#xff0c;非要问你"确定要开门吗&#xff1f;"。我帮客户维护服务器时&#xff0c;发现这个设计本意是好的——防止恶意脚本自动运行。但当…...

PMD自定义规则开发终极指南:打造专属代码质量检查工具

PMD自定义规则开发终极指南&#xff1a;打造专属代码质量检查工具 【免费下载链接】pmd An extensible multilanguage static code analyzer. 项目地址: https://gitcode.com/gh_mirrors/pm/pmd PMD作为一款强大的多语言静态代码分析工具&#xff0c;允许开发者通过自定…...

终极Bloatynosy优化指南:3步打造流畅Windows系统体验

终极Bloatynosy优化指南&#xff1a;3步打造流畅Windows系统体验 【免费下载链接】Bloatynosy The Bloaty and the Nosy: No Bloat, No Problem! 项目地址: https://gitcode.com/gh_mirrors/bl/Bloatynosy Bloatynosy是一款专为Windows系统设计的轻量级优化工具&#xf…...

org.openpnp.vision.pipeline.stages.DetectLinesHough

文章目录org.openpnp.vision.pipeline.stages.DetectLinesHough功能参数例子测试图像generate_line_test_image.pycv-pipeline效果ENDorg.openpnp.vision.pipeline.stages.DetectLinesHough 功能 在图像中检测直线段 在DetectLinesHough之前&#xff0c;需要执行DetectEdgesC…...

重磅曝光!GPT-6 即将登场

大家好&#xff0c;我是十二。专注于分享AI编程方面的内容&#xff0c;欢迎关注。近期&#xff0c;AI圈可谓是“漏风漏得像筛子”&#xff0c;一场关于OpenAI下一代王炸模型&#xff0c;GPT-6的爆料在全网彻底沸腾。根据多方消息透露&#xff0c;OpenAI内部代号为“Spud”&…...