用 Python 撸一个 Web 服务器-第2章:Hello World

从一个 Hello World 程序说起

要编写 Web 服务器,需要用到一个 Python 内置库 socket。Socket 是一个比较抽象的概念,中文叫套接字,它代表一个网络连接。两台计算机之间要进行通讯,大概分为三个步骤:建立连接,传输数据,关闭连接。而 socket 库为我们提供了这个能力。

按照国际惯例,我们将通过编写一个 Hello World 程序来开始 Web 服务器的学习 。

首先要创建一个基于 TCPsocket 对象:

# 导入 socket
import socket

# 创建 socket 对象
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

socket.socket() 方法用来创建一个 socket 对象。同时我们给它传递了两个参数:socket.AF_INET 表示使用IPv4 协议,socket.SOCK_STREAM 表示这是一个基于 TCPsocket 对象。这两个参数也是默认参数,都可以不传。

HTTP 协议是基于请求 —— 响应模型的,请求只可以是客户端发起的,服务器进行响应。服务器并不具备主动发起请求的能力,但是它需要被动的等待客户端的请求。所以现在有了 socket 对象以后我们接下来要做的就是监听客户端的请求:

# 绑定 IP 和端口
sock.bind(('127.0.0.1', 8000))
# 开始监听
sock.listen(5)

socket 对象的 bind 方法用来绑定监听的 IP 地址和端口,它接收一个由 IP 和端口组成的 tuple 作为参数,127.0.0.1 代表本机 IP,只有运行在本机上的浏览器才能连接。端口号允许范围在 0~65535 之间,但是小于 1024 的端口号需要管理员权限才可使用。sock.listen(5) 用来开启监听,等待连接的最大数量指定为 5

开启监听以后,就可以等待接收客户端的请求了:

client, addr = sock.accept()

sock.accept() 会阻塞程序,等待客户端的连接,一旦有客户端连接上来,它会分别返回客户端连接对象和客户端的地址。

与客户端建立好连接后,接下来就是接收客户端发来的请求数据:

data = b''
while True:
    chunk = client.recv(1024)
    data += chunk
    if len(chunk) < 1024:
        break

接收客户端请求数据需要调用客户端连接对象的 recv 方法,参数为每一次接收的数据长度。socket 通讯过程中的数据都为 Python 的 bytes 类型。这里每次接收 1024 个字节,等待数据全部接收完成退出循环。

接收到客户端发来的数据后,就需要对数据进行处理,然后返回响应给客户端的浏览器:

# 打印从客户端接收的数据
print(f'data: {data}')
# 给客户端发送响应数据
client.sendall(b'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>Hello World</h1>')

为了简单起见,在接收到客户端发来的数据后直接进行打印,并没有做进一步的解析处理。接着就是服务器给客户端发送响应数据。发送的数据同样为 bytes 类型。数据按照 HTTP 协议的规范进行组装,首先是状态行 HTTP/1.1 200 OK,紧跟是着一个换行符 \r\n,然后通过响应头 Content-Type: text/html 指定响应结果为 HTML 类型,接下来是两个连续的 \r\n\r\n,注意因为在响应头和响应报文之间隔着一个空行,所以才会出现两个连续的 \r\n\r\n&

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值