klipper/klippy/tcp_server.py

84 lines
2.5 KiB
Python
Raw Normal View History

2024-03-14 03:40:38 +03:00
import socket, threading, logging
def create_server(port):
s = Server(port)
return s.get_backend_fd()
class Server:
def __init__(self, port):
self.port = port
self.socket_backend, self.socket_helper = socket.socketpair()
self.lock = threading.Lock()
self.clients = []
server_address = ('0.0.0.0', port)
self.external_server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
self.external_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.external_server.bind(server_address)
self.external_server.listen()
self.start_copying()
async_accepter = threading.Thread(target=self.server_accept)
async_accepter.daemon = True
async_accepter.start()
def get_backend_fd(self):
return self.socket_backend.fileno()
def server_accept(self):
self.accept_in_loop()
def start_copying(self):
async_writer = threading.Thread(target=self.write_to_clients)
async_writer.daemon = True
async_writer.start()
def accept_in_loop(self):
while True:
try:
conn, address = self.external_server.accept()
except Exception as e:
logging.info("Server: accept error: ", e)
pass
# logging.info("Server: accepted: "+ str(address))
conn.setblocking(False)
self.lock.acquire()
self.clients.append(conn)
self.lock.release()
async_reader = threading.Thread(target=self.read_from_client, args=(conn,))
async_reader.daemon = True
async_reader.start()
def read_from_client(self, conn):
while True:
try:
data = conn.recv(1024)
if data:
# logging.info("Server: in: "+ str(data))
self.socket_helper.sendall(data)
except Exception as e:
""
def write_to_clients(self):
while True:
self.lock.acquire()
clients = self.clients
self.lock.release()
if len(clients) == 0:
continue
try:
data = self.socket_helper.recv(1024)
if data:
# logging.info("Server: out: "+ str(data))
for c in clients:
c.sendall(data)
except Exception as e:
""