Added input TCP option

This commit is contained in:
Nikolay Kopitonenko 2024-03-14 03:40:38 +03:00
parent b07cfbeede
commit 3c9b56f020
2 changed files with 88 additions and 1 deletions

View File

@ -6,7 +6,7 @@
# This file may be distributed under the terms of the GNU GPLv3 license. # This file may be distributed under the terms of the GNU GPLv3 license.
import sys, os, gc, optparse, logging, time, collections, importlib import sys, os, gc, optparse, logging, time, collections, importlib
import util, reactor, queuelogger, msgproto import util, reactor, queuelogger, msgproto
import gcode, configfile, pins, mcu, toolhead, webhooks import gcode, configfile, pins, mcu, toolhead, webhooks, tcp_server
message_ready = "Printer is ready" message_ready = "Printer is ready"
@ -303,6 +303,8 @@ def main():
opts.add_option("-I", "--input-tty", dest="inputtty", opts.add_option("-I", "--input-tty", dest="inputtty",
default='/tmp/printer', default='/tmp/printer',
help="input tty name (default is /tmp/printer)") help="input tty name (default is /tmp/printer)")
opts.add_option("-T", "--input-tcp-port", dest="inputtcpport",
help="input TCP port")
opts.add_option("-a", "--api-server", dest="apiserver", opts.add_option("-a", "--api-server", dest="apiserver",
help="api server unix domain socket filename") help="api server unix domain socket filename")
opts.add_option("-l", "--logfile", dest="logfile", opts.add_option("-l", "--logfile", dest="logfile",
@ -331,6 +333,8 @@ def main():
start_args['debuginput'] = options.debuginput start_args['debuginput'] = options.debuginput
debuginput = open(options.debuginput, 'rb') debuginput = open(options.debuginput, 'rb')
start_args['gcode_fd'] = debuginput.fileno() start_args['gcode_fd'] = debuginput.fileno()
elif options.inputtcpport:
start_args['gcode_fd'] = tcp_server.create_server(int(options.inputtcpport))
else: else:
start_args['gcode_fd'] = util.create_pty(options.inputtty) start_args['gcode_fd'] = util.create_pty(options.inputtty)
if options.debugoutput: if options.debugoutput:

83
klippy/tcp_server.py Normal file
View File

@ -0,0 +1,83 @@
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:
""