面向连接的并发服务器
def main():
# 1. 创建socket套接字
tcp_server = socket(AF_INET, SOCK_STREAM)
# 2. 绑定IP地址和端口
tcp_server.bind(("", 8888))
# 3. 把主动模式变成被动模式 只能接收 不能发送数据
tcp_server.listen(5)
while True:
# 4. 等待客户端连接
new_socket, client_info = tcp_server.accept()
print(f"新的客户端来了 {client_info}")
# 5. 接收数据
raw_data = new_socket.recv(1024)
while raw_data:
print(f"收到{client_info}数据: {raw_data}")
# 再次取
raw_data = new_socket.recv(1024)
# 6.关闭新套接字
new_socket.close()
if __name__ == '__main__':
main()
只能同时为一个人服务
多进程并发服务器
from socket import *
from multiprocessing import Process
def rec_data(client_info, new_socket):
"""新套接字处理数据"""
raw_data = new_socket.recv(1024)
while raw_data:
print(f"收到{client_info}数据: {raw_data}")
# 再次取
raw_data = new_socket.recv(1024)
# 关闭套接字
new_socket.close()
def main():
# 1. 创建socket套接字
tcp_server = socket(AF_INET, SOCK_STREAM)
# 2. 绑定IP地址和端口
tcp_server.bind(("", 7777))
# 3. 把主动模式变成被动模式 只能接收 不能发送数据
tcp_server.listen(5)
while True:
# 4. 等待客户端连接
new_socket, client_info = tcp_server.accept()
print(f"新的客户端来了 {client_info}")
# 5. 接收数据
# rec_data(client_info, new_socket)
# 6.创建新的进程
p = Process(target=rec_data, args=(client_info, new_socket))
# 6.1 启动进程
p.start()
# 6.关闭新套接字 多进程必需关闭new_socket 因为会复制出来一个新的
new_socket.close()
if __name__ == '__main__':
main()
多进程服务器代表:Apache服务器
主进程中必需关闭new_socket.close()
多线程并发服务器
from socket import *
from threading import Thread
def rec_data(client_info, new_socket):
"""新套接字处理数据"""
raw_data = new_socket.recv(1024)
while raw_data:
print(f"收到{client_info}数据: {raw_data}")
# 再次取
raw_data = new_socket.recv(1024)
# 关闭套接字
new_socket.close()
def main():
# 1. 创建socket套接字
tcp_server = socket(AF_INET, SOCK_STREAM)
# 2. 绑定IP地址和端口
tcp_server.bind(("", 7788))
# 3. 把主动模式变成被动模式 只能接收 不能发送数据
tcp_server.listen(5)
while True:
# 4. 等待客户端连接
new_socket, client_info = tcp_server.accept()
print(f"新的客户端来了 {client_info}")
# 5. 接收数据
# rec_data(client_info, new_socket)
# 6.创建新的进程
p = Thread(target=rec_data, args=(client_info, new_socket))
# 6.1 启动进程
p.start()
# 6.关闭新套接字
#new_socket.close()
if __name__ == '__main__':
main()
多线程代表:IIS服务器
子线程共享主线程的变量,所以主线程中不能关闭new_socket.close(),否则子线程也会断开连接
单进程非阻塞版并发服务器
from socket import *
def main():
# 1. 创建socket套接字
tcp_server = socket(AF_INET, SOCK_STREAM)
# 2. 把套接字设置成非阻塞
tcp_server.setblocking(False)
# 2. 绑定IP地址和端口
tcp_server.bind(("", 6667))
# 3. 把主动模式变成被动模式 只能接收 不能发送数据
tcp_server.listen(5)
# 4. 声明一个列表用来存新的套接字
socket_lists = []
while True:
try:
# 4. 等待客户端连接
new_socket, client_info = tcp_server.accept()
# 4.1 设置new_socket为非阻塞
new_socket.setblocking(False)
except:
pass
else:
"""已经有人连接,取到数据了"""
# 把新的套接字往列表里扔
socket_lists.append((new_socket, client_info))
print(f"新的客户端来了 {client_info}")
# 循环列表
for sock, client_info in socket_lists:
try:
# 让每一个new_socket去接收数据 又阻塞了,应该在创建new_socket后设置新的套接字为 非阻塞
raw_data = sock.recv(1024)
except:
pass
else:
# 当客户端断开的时候 raw_data 就是空
if raw_data:
print(f"收到{client_info}数据:{raw_data.decode('gb2312')}")
else:
# 客户端断了
sock.close()
# 列表移除
socket_lists.remove((sock, client_info))
if __name__ == '__main__':
main()
网友评论