为什么我的 TCP 服务器不接受多个客户端连接?



我在TCP服务器下面写过,我不知道为什么处理程序不支持多个TCP客户端连接。

import socket
import sys
import ast
# Internal imports
import core
try:
import fcntl
except ImportError:
fcntl = None
import logging
import json
_LOG = logging.getLogger(__name__)
if sys.version_info.major == 2:
import SocketServer
TCPServer = SocketServer.TCPServer
RequestHandler = SocketServer.BaseRequestHandler
if sys.version_info.major == 3:
import socketserver
TCPServer = socketserver.TCPServer
RequestHandler = socketserver.BaseRequestHandler

class TCPServerRequestHandler(RequestHandler):
def handle(self):
"""Receives data from client.
"""
msg = self.request.recv(1024).strip()
if self.client_address and not msg:
_LOG.error("No Data revieved from Client: {}".format(self.client_address[0]))
return
# Send some data to client
# self.wfile.write("Hello Client....Got your message".encode())
data = ast.literal_eval(msg.decode('utf-8'))
if not data:
_LOG.error("No data recieved.")
else:
with core._connect(db="exampledb") as conn:
if "device" in data and data["device"] == "mcu":
table_name = "roku_online_status"
if conn:
data.pop("device")
cols = [c for c in data.keys()] # python 3 dict keys is not list
stored_value = core.doQuery(conn, table_name, cols, "id")
if stored_value[0] != data["online"]:
core.insert_row(data, table_name, conn)
else:
if conn:
core.insert_row(data, "particle_photon", conn)
conn.close()

class Server(TCPServer):
allow_reuse_address = True
# The constant would be better initialized by a systemd module
SYSTEMD_FIRST_SOCKET_FD = 3
def __init__(self, server_address, handler_cls, bind_and_activate=True):
self.handlers = set()
# Invoke base but omit bind/listen steps (performed by systemd activation!)
try:
TCPServer.__init__(self, server_address, handler_cls, bind_and_activate)
except TypeError:
TCPServer.__init__(self, server_address, handler_cls)
# Override socket
self.socket = socket.fromfd(
self.SYSTEMD_FIRST_SOCKET_FD, self.address_family, self.socket_type)
if fcntl is not None and hasattr(fcntl, 'FD_CLOEXEC'):
flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD)
flags |= fcntl.FD_CLOEXEC
fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags)
def server_bind(self):
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(self.server_address)
def server_close(self):
TCPServer.server_close(self)
print("Shutting down server.")
for handler in self.handlers.copy():
print(handler)
self.shutdown_request(handler.request)

def main(server_address):
"""Starts TCPServer.
"""
logging.basicConfig(level=logging.DEBUG)
# Create a TCP Server instance
server = Server(server_address, TCPServerRequestHandler)
try:
server.serve_forever()
except KeyboardInterrupt:
sys.exit(0)

if __name__ == '__main__':
main(("10.10.10.2", 7111))

对于单个连接,它工作正常,但是当多个客户端尝试连接时,它会卡住。

您已经实现了具有阻塞 I/O 的单线程服务器。这种服务器一次只能处理一个客户端,因为它等到客户端完成(TCPServerRequestHandler内部(后才能处理下一个客户端的连接。

要同时处理多个客户端,您要么必须使用多个线程或进程,其中每个线程或进程可以处理单个客户端,要么必须实现一个基于事件的服务器,该服务器可以在单个线程中处理多个客户端。要实现第一个,你可以看看ThreadingTCPServer和ForkingTCPServer,对于后者,看看像Twisted这样的框架。

最新更新