实现简单的web框架中接受请求和返回请求的功能, 可以用于学习网络通信
githup: OneFile/web-server.py at main · 521xueweihan/OneFile · GitHub
处理连接
这里需要简单聊一下 socket 这个东西,在编程语言层面它就是一个类库,负责搞定连接建立网络通信。但本质上是系统级别提供通信的进程,而一台电脑可以建立多条通信线路,所以每一个端口号后面都是一个 socket 进程,它们相互独立、互不干涉,这也是为什么我们在启动服务的时候要指定端口号的原因。
最后,上面所说的服务器其实就是一台性能好一点、一直开着的电脑,而客户端就是浏览器、手机、电脑,它们都有 socket 这个东西(操作系统级别的一个进程)。
如果上面这段话没有看懂也不碍事,能看懂下面的图就行,得搞明白 socket 处理连接的步骤和流程,才能编写 Web 框架处理连接的部分。
下面分别展示基于 socket 编写的 server.py 和 client.py 代码。
# coding: utf-8
# 服务器端代码(server.py)
import socket
print('我是服务端!')
HOST = ''
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建 TCP socket 对象
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 重启时释放端口
s.bind((HOST, PORT)) # 绑定地址
s.listen(1) # 监听TCP,1代表:操作系统可以挂起(未处理请求时等待状态)的最大连接数量。该值至少为1
print('监听端口:', PORT)
while 1:
conn, _ = s.accept() # 开始被动接受TCP客户端的连接。
data = conn.recv(1024) # 接收TCP数据,1024表示缓冲区的大小
print('接收到:', repr(data))
conn.sendall(b'Hi, '+data) # 给客户端发送数据
conn.close()
因为 HTTP 是建立在相对可靠的 TCP 协议上,所以这里创建的是 TCP socket 对象。
# coding: utf-8
# 客户端代码(client.py)
import socket
print('我是客户端!')
HOST = 'localhost' # 服务器的IP
PORT = 50007 # 需要连接的服务器的端口
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
print("发送'HelloGitHub'")
s.sendall(b'HelloGitHub') # 发送‘HelloGitHub’给服务器
data = s.recv(1024)
s.close()
print('接收到', repr(data)) # 打印从服务器接收回来的数据
运行效果如下:
结合上面的代码,可以更加容易理解 socket 建立通信的流程:
- socket:创建socket
- bind:绑定端口号
- listen:开始监听
- accept:接收请求
- recv:接收数据
- close:关闭连接