Python 使用 Socket 从零写一个HTTP服务器

有些东西我讲得并不是很好. 有异议或疑惑的地方可以在评论区或私信指出. 欢迎加群: 905329304 一起学习讨论, (只讲最基础的内容, 最后形成靠大家自己来)

最好有Socket基础,本章有一个并不是很重要的错误(彩蛋), 你能找到吗? 提示: 关于Django的, 我的操作导致了原本不该出现的漏洞

HTTP数据包结构

别的不多说我们先来了看一下HTTP的数据包结构, 分为三部分, 请求第一行为请求行, 这里标识请求方法请求路由地址和协议版本, 下面是请求头, 可以理解为请求的附带信息. 空一行回车符和换行符表示请求头结束, 以下是请求体的数据 

HTTP 数据包结构

请求数据包实例

我们来看一个POST请求的请求数据包, 这是用 Burpsuite 拦截下来的请求

你可能会发现这里怎么没有你所谓的回车符(\r)和换行符(\n)呢, 实际上你看到的这个是编译后的... 换行符和回车符都变成了换行, 我们下面用socket接受浏览器请求查看他数据包的时候就能看到了

POST请求数据包

我将上面这个文本请求的数据包放到刚才的结构中看一下.

使用 Python Socket 接受浏览器请求(接受浏览器发送的HTTP请求数据包)

我们先使用 socket 实现一个一个最简单可以接受连接和数据的服务器

用浏览器访问看一下是最后的数据输出的是什么, 

忘记说了你看到字符串前面有个 b 表示这个是字节流数据,可以看到这些数据其实全都是挤在一行的只不过是\r\n他们看起来有换行而已,

最后打印的时候我们使用 decode() 方法让他看起来更好看一些

这样就得到了浏览器发送的GET请求了,那么我们用POST发送一个POST请求

细心的同学可能发现了, 与浏览器发起没有请求体的GET请求比起我们的请求头多了 Content-Length , 这表示请求体内容长度, 也就是发送数据的长度

修改优化接收数据

上面我们接收数据用是循环取, 如果接收的数据长度小于我们接收的长度正面没有数据了跳出循环

这样可能导致死循环, 程序卡死, 而且这样不利于我们后期处理数据, 所有我们使用另外一种方法

我们使用makefile方法 该方法返回与套接字关联的文件对象。返回的确切类型取决于赋予makefile()的参数。这些参数的解释方式与内置的open()函数相同

也就是说我们使用makefile方法可以想读文件一样取我们的数据他的类型为: <class '_io.BufferedReader'>

还是使用 Postman 发送一个 post 请求

可以看到这样我们可以根据自己的需要取读取多少行, 我们还可以使用 read() 方法读取相应长度的数据

本期先到这里.. 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值