分享一个之前写的课设作业,这是main.py,使用select来异步建立socket连接和收发socket数据
然后由TCPHandler处理消息,之前用的是json,要用xml的话自己写就是了
另外感觉没必要开两个端口,消息可以用cmd区分类型,用一个socket足以
[Python] 纯文本查看 复制代码
import select
import socket
import sys
from queue import Empty, Queue
from socket import socket as Socket
from core.tcp_handler import TCPHandler
from core.utils import log
LISTEN_ON = '0.0.0.0'
RECV_BYTES = 8192
def main(host, port):
# Init TCP server
tcp_socket = Socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_socket.setblocking(False)
try:
tcp_socket.bind((host, port))
tcp_socket.listen(10)
log(f'TCP server listening on {host}:{port}', None, False)
except OSError as s:
log(f'TCP server start error: {s}', None, True)
return
# Init TCPHandler
tcp_handler = TCPHandler()
log('Wating for clients ...', None, False)
# Event loop
try:
inputs = [tcp_socket, ]
outputs = []
msg_queue = {}
while True:
rlist, wlist, elist = select.select(inputs, outputs, inputs, 1)
for s in rlist:
# any socket is ready for reading
if s == tcp_socket:
# TCP incoming connection
conn, addr = s.accept()
conn.setblocking(False)
inputs.append(conn)
msg_queue[conn] = Queue()
# log('TCP connection established', addr, False)
else:
data = s.recv(RECV_BYTES)
addr = s.getpeername()
if data:
# TCP message
response = tcp_handler.handle_message(data, addr)
msg_queue[s].put(response)
if s not in outputs:
outputs.append(s)
else:
# TCP close
# log('TCP connection closed', addr, True)
if s in outputs:
outputs.remove(s)
inputs.remove(s)
s.close()
msg_queue.pop(s, None)
for s in wlist:
# any socket is ready for writing
try:
payload = msg_queue[s].get_nowait()
s.send(payload)
outputs.remove(s)
msg_queue.pop(s, None)
except Empty:
pass
for s in elist:
# any socket raises error
log('TCP connection error', None, True)
inputs.remove(s)
if s in outputs:
outputs.remove(s)
msg_queue.pop(s, None)
s.close()
except KeyboardInterrupt:
pass
finally:
tcp_socket.close()
log('Server shutdown ...', None, True)
if __name__ == '__main__':
try:
port = int((sys.argv[1:] or ['12345'])[0])
if port < 0 or port > 65535:
raise ValueError
except ValueError:
log('Usage: python3 server.py [port]', None, True)
log('Default port is 12345', None, True)
input('Press enter to exit...')
exit(1)
main(LISTEN_ON, port)
[Python] 纯文本查看 复制代码
class TCPHandler():
def handle_message(self, raw: bytes, addr: Tuple[str, int]):
try:
response = None
# addr = sock.getpeername()
payload = json_deserializer(raw)
# 这里处理消息
except:
pass
|