欢迎阅读本文,本文将全面讲解 Python 实现 socket 服务端并发的四种方式,包括:
1.多线程方式
2.多进程方式
3.select 方式
4.EPOLL方式
多线程方式
-
基于 socket 创建服务端套接字,使用
bind()
方法让服务端套接字与固定 IP 和端口绑定,使用listen()
方法开始监听客户端连接; -
在监听客户端连接之后,使用
accept()
方法接收客户端连接,每接收一个连接就创建一个新线程,用于与客户端通信; -
同时创建的线程数量最好不要过多,过多的线程会导致资源浪费,也会影响程序效率。
以下是示例代码:
import socket
import threading
def client_handler(client_socket, addr):
print('New connection from', addr)
while True:
try:
data = client_socket.recv(1024)
if not data:
break
client_socket.sendall(data) # 自动回传消息
except:
break
client_socket.close()
def main():
host = '127.0.0.1'
port = 5000
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((host,port))
server_socket.listen(5)
while True:
client_socket, addr = server_socket.accept()
t = threading.Thread(target=client_handler, args=(client_socket, addr))
t.start()
if __name__ == '__main__':
main()
多进程方式
-
基于 socket 创建服务端套接字,使用
bind()
方法让服务端套接字与固定 IP 和端口绑定,使用listen()
方法开始监听客户端连接; -
在监听客户端连接之后,使用
accept()
方法接收客户端连接,每接收一个连接就创建一个新进程,用于与客户端通信; -
同时创建的进程数量最好不要过多,过多的进程会导致资源浪费,也会影响程序效率。
以下是示例代码:
import socket
import multiprocessing
def client_handler(client_socket, addr):
print('New connection from', addr)
while True:
try:
data = client_socket.recv(1024)
if not data:
break
client_socket.sendall(data) # 自动回传消息
except:
break
client_socket.close()
def main():
host = '127.0.0.1'
port = 5000
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((host,port))
server_socket.listen(5)
while True:
client_socket, addr = server_socket.accept()
p = multiprocessing.Process(target=client_handler, args=(client_socket, addr))
p.start()
if __name__ == '__main__':
main()
Select方式
1.基于 socket 创建服务端套接字,使用 bind()
方法让服务端套接字与固定 IP 和端口绑定,使用 listen()
方法开始监听客户端连接;
2.在监听客户端连接之后,通过 select
方法来选择读取,每当有新的客户端连接时,通过 accept()
方法来接收客户端连接。
以下是示例代码:
import socket
import select
def main():
host = '127.0.0.1'
port = 5000
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((host,port))
server_socket.listen(5)
read_list = [server_socket]
while True:
readable, writable, _ = select.select(read_list, [], [])
for s in readable:
if s is server_socket:
client_socket, addr = server_socket.accept()
read_list.append(client_socket)
print('New connection from', addr)
else:
data = s.recv(1024)
if not data:
read_list.remove(s)
s.close()
continue
s.sendall(data) # 自动回传消息
if __name__ == '__main__':
main()
EPOLL方式
-
基于 socket 创建服务端套接字,使用
bind()
方法让服务端套接字与固定 IP 和端口绑定,使用listen()
方法开始监听客户端连接; -
在监听客户端连接之后,通过
epoll
方法来选择读取,每当有新的客户端连接时,通过accept()
方法来接收客户端连接。
以下是示例代码:
import socket
import select
def main():
host = '127.0.0.1'
port = 5000
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((host,port))
server_socket.listen(5)
epoll = select.epoll()
epoll.register(server_socket.fileno(), select.EPOLLIN)
connections = {}
while True:
events = epoll.poll(1)
for fileno, event in events:
if fileno == server_socket.fileno():
# 接受客户端连接
client_socket, client_address = server_socket.accept()
print('New connection from', client_address)
connections[client_socket.fileno()] = client_socket
epoll.register(client_socket.fileno(), select.EPOLLIN)
elif event & select.EPOLLIN:
# 接收客户端数据
client_socket = connections[fileno]
data = client_socket.recv(1024)
if data:
client_socket.sendall(data) # 自动回传消息
else:
epoll.unregister(fileno)
client_socket.close()
del connections[fileno]
epoll.unregister(server_socket.fileno())
epoll.close()
server_socket.close()
if __name__ == '__main__':
main()
总结:
本文介绍了四种 Python 实现 socket 服务端并发的方式,分别是多线程方式、多进程方式、select 方式、EPOLL方式。不同的方式有不同的应用场景,开发者们可以根据需要进行选择,提高程序运行效率。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python 实现socket服务端并发的四种方式 - Python技术站