"""tcp服务器端面向函数(进程,线程,协程对比)
结论在进程+协程服务器的效率最优秀"""
# 一.进程版
import socket
import re
import time
import multiprocessing
def main():
tcp_server = init_server()
# 循环去处理客户请求
run_server(tcp_server)
def run_server(tcp_server):
"""运行服务"""
while True:
client, addr = tcp_server.accept()
# print(addr) F2定位错误
# client_exec(client)
#让我们的多进程去服务器我们的客户端处理
process = multiprocessing.Process(target=client_exec, args=(client,))
process.start() #启动 #会复制进程前的资源,操作系统在关闭资源的时间会检查资源的引用,如果全部结束才会回收资源
# client.fileno()这个操作系统的文件标识符
#关闭客户端资源
client.close() #fd文件标识符
# 关闭服务器
tcp_server.close()
def client_exec(client):
print(client)
"""这个就是单独客户端的处理"""
# 接收数据
data = client.recv(1024).decode()
head_lines = data.splitlines()
try:
print(head_lines[0])
# GET /index.html HTTP/1.1
# 使用正则去获取地址
re_match = re.match(r'[^/]+(/[^ ]*)', head_lines[0])
# 判断是否匹配了
if re_match: # 匹配 了
file_name = re_match.group(1)
# 如果是/那么去首页
if file_name == "/":
file_name = "/index.html"
except Exception as e:
print(e) # 工作中是记录到文件
# 返回数据
# 响应头
# 空行
# 响应体
try:
headers = "HTTP/1.1 200 OK\r\n"
# 会根据不同的地址返回不的内容
# 打开文件写读文件内容
with open("./html%s" % file_name, 'rb') as f: # 这样写有一个好处,如果是图片就不会有问题
body = f.read() # 读取文件
# body = "show page is find!"
# content = headers +"\r\n" +body
content = headers + "\r\n"
# client.send(content.encode("utf-8"))
client.send(content.encode("utf-8"))
client.send(body)
except Exception as e:
print(e)
# 返回一个404的正常显示的页面
head = "HTTP/1.1 404 NOT FIND\r\n"
body = "not find page!"
content = head + "\r\n" + body
client.send(content.encode("utf-8"))
# 关闭客户端
client.close()
def init_server(): # ctrl+B进入到函数
""" 初始化tcp服务器"""
# 服务器tcp服务器对象
tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置我们的端口地址重用
tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定端口号
tcp_server.bind(("", 6789))
# 改成被动模式
tcp_server.listen(128)
return tcp_server
if __name__ == '__main__':
main()
# 二.线程版:
import socket
import re
import time
import threading
def main():
tcp_server = init_server()
# 循环去处理客户请求
run_server(tcp_server)
def run_server(tcp_server):
"""运行服务"""
while True:
client, addr = tcp_server.accept()
# print(addr) F2定位错误
# client_exec(client)
#让我们的多进程去服务器我们的客户端处理
# process = multiprocessing.Process(target=client_exec, args=(client,))
# process.start() #启动 #会复制进程前的资源,操作系统在关闭资源的时间会检查资源的引用,如果全部结束才会回收资源
#
# # client.fileno()这个操作系统的文件标识符
# #关闭客户端资源
# client.close() #fd文件标识符
threading_thread = threading.Thread(target=client_exec, args=(client,))
threading_thread.start()
# 关闭服务器
tcp_server.close()
def client_exec(client):
print(client)
time.sleep(10)
"""这个就是单独客户端的处理"""
# 接收数据
data = client.recv(1024).decode()
head_lines = data.splitlines()
try:
print(head_lines[0])
# GET /index.html HTTP/1.1
# 使用正则去获取地址
re_match = re.match(r'[^/]+(/[^ ]*)', head_lines[0])
# 判断是否匹配了
if re_match: # 匹配 了
file_name = re_match.group(1)
# 如果是/那么去首页
if file_name == "/":
file_name = "/index.html"
except Exception as e:
print(e) # 工作中是记录到文件
# 返回数据
# 响应头
# 空行
# 响应体
try:
headers = "HTTP/1.1 200 OK\r\n"
# 会根据不同的地址返回不的内容
# 打开文件写读文件内容
with open("./html%s" % file_name, 'rb') as f: # 这样写有一个好处,如果是图片就不会有问题
body = f.read() # 读取文件
# body = "show page is find!"
# content = headers +"\r\n" +body
content = headers + "\r\n"
# client.send(content.encode("utf-8"))
client.send(content.encode("utf-8"))
client.send(body)
except Exception as e:
print(e)
# 返回一个404的正常显示的页面
head = "HTTP/1.1 404 NOT FIND\r\n"
body = "not find page!"
content = head + "\r\n" + body
client.send(content.encode("utf-8"))
# 关闭客户端
client.close()
def init_server(): # ctrl+B进入到函数
""" 初始化tcp服务器"""
# 服务器tcp服务器对象
tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置我们的端口地址重用
tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定端口号
tcp_server.bind(("", 6789))
# 改成被动模式
tcp_server.listen(128)
return tcp_server
if __name__ == '__main__':
main()
#三.协程版:
import socket
import re
import time
import gevent
from gevent import monkey
#让我们的系统把所有的耗时操作转换成gevent的
monkey.patch_all()
def main():
tcp_server = init_server()
# 循环去处理客户请求
run_server(tcp_server)
def run_server(tcp_server):
"""运行服务"""
while True:
client, addr = tcp_server.accept()
# print(addr) F2定位错误
# client_exec(client)
#让我们的多进程去服务器我们的客户端处理
gevent_spawn = gevent.spawn(client_exec, client)
# gevent_spawn.join()
# 关闭服务器
tcp_server.close()
def client_exec(client):
print(client)
"""这个就是单独客户端的处理"""
# 接收数据
data = client.recv(1024).decode()
head_lines = data.splitlines()
try:
print(head_lines[0])
# GET /index.html HTTP/1.1
# 使用正则去获取地址
re_match = re.match(r'[^/]+(/[^ ]*)', head_lines[0])
# 判断是否匹配了
if re_match: # 匹配 了
file_name = re_match.group(1)
# 如果是/那么去首页
if file_name == "/":
file_name = "/index.html"
except Exception as e:
print(e) # 工作中是记录到文件
# 返回数据
# 响应头
# 空行
# 响应体
try:
headers = "HTTP/1.1 200 OK\r\n"
# 会根据不同的地址返回不的内容
# 打开文件写读文件内容
with open("./html%s" % file_name, 'rb') as f: # 这样写有一个好处,如果是图片就不会有问题
body = f.read() # 读取文件
# body = "show page is find!"
# content = headers +"\r\n" +body
content = headers + "\r\n"
# client.send(content.encode("utf-8"))
client.send(content.encode("utf-8"))
client.send(body)
except Exception as e:
print(e)
# 返回一个404的正常显示的页面
head = "HTTP/1.1 404 NOT FIND\r\n"
body = "not find page!"
content = head + "\r\n" + body
client.send(content.encode("utf-8"))
# 关闭客户端
client.close()
def init_server(): # ctrl+B进入到函数
""" 初始化tcp服务器"""
# 服务器tcp服务器对象
tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置我们的端口地址重用
tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定端口号
tcp_server.bind(("", 6789))
# 改成被动模式
tcp_server.listen(128)
return tcp_server
if __name__ == '__main__':
main()
Python tcp服务器端面向函数(进程,线程,协程对比) 三份源码!
最新推荐文章于 2023-10-13 09:53:36 发布