前言
利用 Python 标准库 socket 实现多线程 echo 和 http 程序.
源教程地址: https://www.bilibili.com/video/BV1eg411G7pW/?vd_source=547d8a3d2ce70a88f0a699636396bd6f .
想要了解套接字更多的内容可以阅读 TCP/IP网络编程.
操作系统:Ubuntu 20.04.6 LTS
参考文档
echo
- 在服务器上编写
server.py
。服务器 IP 地址为10.4.3.155
。
# nc 是linux 下网络测试工具, 可以读写 TCP/UDP 的数据
# Windows 的替代版本 (nmap): https://nmap.org/
# 使用方法,在客户端运行下面命令:
#
# nc 服务器IP地址 端口号
#
# 本案例的测试命令为:
#
# nc 10.4.3.155 1234
import socket
import threading
import os
WEBROOT = os.path.dirname(__file__)
# echo 程序
def handle_client(c, addr):
print(addr, "connected.")
while True:
data = c.recv(1024)
if not data:
break
c.sendall(data)
# http 程序
def handle_http(c, addr):
print(addr, "connected.")
with c:
request = c.recv(1024)
# Parse HTTP headers
headers = request.split(b"\r\n")
file = headers[0].split()[1].decode()
# Load file content
if file == "/":
file = "/index.html"
try:
with open(WEBROOT + file, "rb") as f:
content = f.read()
response = b"HTTP/1.0 200 OK\r\n\r\n" + content
except FileNotFoundErrot:
response = b"HTTP/1.0 404 NOT FOUND\r\n\r\nFile not found!"
# Send HTTP response
c.sendall(response)
# socket.AF_INET 表示 IPv4 地址家族
# socket.SOCK_STREAM 表示 TCP 协议
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
# 服务器 IP 地址, 即运行本脚本的主机地址
s.bind(("10.4.3.155", 1234))
s.listen()
while True:
c, addr = s.accept()
t = threading.Thread(target=handle_client, args=(c, addr))
#t = threading.Thread(target=handle_http, args=(c, addr))
t.start()
- 在本地计算机上编写客户端脚本
client.py
。
#!/usr/bin/env python
# coding=utf-8
import socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect(("10.4.3.155", 1234))
s.sendall(b"Hello, lyf!")
data = s.recv(1024)
print("Received: ", repr(data))
在服务器上运行
server.py
。在客户端上运行
client.py
。
运行结果
- 服务器:
(base) luyanfeng@amax:~/my_code/temp$ ls
index.html server.py
(base) luyanfeng@amax:~/my_code/temp$ python server.py
('10.4.3.151', 47222) connected.
('10.4.3.151', 40348) connected.
('10.4.3.151', 53850) connected.
^CTraceback (most recent call last):
File "/home/luyanfeng/my_code/temp/server.py", line 60, in <module>
c, addr = s.accept()
File "/home/luyanfeng/miniconda3/lib/python3.9/socket.py", line 293, in accept
fd, addr = self._accept()
KeyboardInterrupt
(base) luyanfeng@amax:~/my_code/temp$
- 客户端:
(base) lyfubuntu@lyfubuntu:~/my_computer_language/temp$ ls
client.py
(base) lyfubuntu@lyfubuntu:~/my_computer_language/temp$ python client.py
Received: b'Hello, lyf!'
(base) lyfubuntu@lyfubuntu:~/my_computer_language/temp$ python client.py
Received: b'Hello, lyf!'
(base) lyfubuntu@lyfubuntu:~/my_computer_language/temp$ python client.py
Received: b'Hello, lyf!'
(base) lyfubuntu@lyfubuntu:~/my_computer_language/temp$
http
- 在服务器上编写
server.py
。服务器 IP 地址为10.4.3.155
。
# nc 是linux 下网络测试工具, 可以读写 TCP/UDP 的数据
# Windows 的替代版本 (nmap): https://nmap.org/
# 使用方法,在客户端运行下面命令:
#
# nc 服务器IP地址 端口号
#
# 本案例的测试命令为:
#
# nc 10.4.3.155 1234
import socket
import threading
import os
WEBROOT = os.path.dirname(__file__)
# echo 程序
def handle_client(c, addr):
print(addr, "connected.")
while True:
data = c.recv(1024)
if not data:
break
c.sendall(data)
# http 程序
def handle_http(c, addr):
print(addr, "connected.")
with c:
request = c.recv(1024)
# Parse HTTP headers
headers = request.split(b"\r\n")
file = headers[0].split()[1].decode()
# Load file content
if file == "/":
file = "/index.html"
try:
with open(WEBROOT + file, "rb") as f:
content = f.read()
response = b"HTTP/1.0 200 OK\r\n\r\n" + content
except FileNotFoundErrot:
response = b"HTTP/1.0 404 NOT FOUND\r\n\r\nFile not found!"
# Send HTTP response
c.sendall(response)
# socket.AF_INET 表示 IPv4 地址家族
# socket.SOCK_STREAM 表示 TCP 协议
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
# 服务器 IP 地址, 即运行本脚本的主机地址
s.bind(("10.4.3.155", 1234))
s.listen()
while True:
c, addr = s.accept()
#t = threading.Thread(target=handle_client, args=(c, addr))
t = threading.Thread(target=handle_http, args=(c, addr))
t.start()
- 在
server.py
同级目录下编写index.html
。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My test page</title>
</head>
<body>
<p>My cat is very grumpy</p>
</body>
</html>
- 在服务器上运行
server.py
。
运行结果
- 打开本地浏览器,输入
http://10.4.3.155:1234/
。
结语
第七十一篇博文写完,开心!!!!
今天,也是充满希望的一天。