TCP server for sharing a serial console across multiple TCP clients.
clientA <-->\
| <-----> TcpServer <---> serial port
clientB <-->/
The serial port opens when the first client connects and closes when the last client disconnects. If the serial device is lost, all TCP clients are kept connected while the server attempts to reconnect.
Works on Windows and Linux (including Raspberry Pi).
- Python >= 3.9
- pyserial >= 3.3
pip install serial-tcp-clientsThis installs the CLI/backend only (depends on pyserial alone — no GUI, no
Tkinter, no PyYAML). For the desktop app see GUI (Port Manager),
which is a separate serial-tcp-clients-gui package.
Or from source:
git clone https://github.com/maslovw/serial_tcp_clients.git
cd serial_tcp_clients
pip install .serial-tcp-server -p PORT -d DEVICE -b BAUDRATEOr via module:
python -m serialtcp -p PORT -d DEVICE -b BAUDRATEoptional arguments:
-h, --help show this help message and exit
--list print list of serial devices
-v {debug,info,warn,error,fatal}, --verbose {debug,info,warn,error,fatal}
logger level, default: error
TCP connection:
-p TCP_PORT, --tcp-port TCP_PORT
TCP listen port
serial port:
-d DEVICE, --device DEVICE
serial port/device
-b BAUDRATE, --baudrate BAUDRATE
default: 115200
--parity {N,E,O,S,M} set parity, one of {N E O S M}, default: N
--xonxoff enable software flow control (default off)
-cd CHAR_DELAY, --char-delay CHAR_DELAY
set delay between chars for serial transmission,
default: 0.0s
-we WAIT_ECHO, --wait-echo WAIT_ECHO
wait for echo char when transmitting, value represents
timeout in seconds, default: 0
serial-tcp-server -p 5001 -d COM1 -b 921600 -v info -we 1Use -v debug to send connection status messages (device, baudrate,
connect/disconnect events) to TCP clients.
A separate Tkinter desktop app (the serial-tcp-clients-gui package, built on
the CLI/backend) manages many serial -> TCP mappings at once from a single
YAML config. It uses a master-detail layout: a list of port cards on the left,
and the selected port's console, settings, throughput and live log on the right.
For each mapping you can Start/Stop the TCP listener, watch live OUT/IN throughput, the connected-client count and the serial device's link state (a green/grey port chip), read a colour-coded console, send data to the serial device from a console input line, and Add/Edit/Remove mappings. The serial port opens when the first TCP client connects and closes when the last disconnects; if the device drops, the clients stay connected while the GUI shows a "reconnecting" banner and retries.
- Python >= 3.9
- pyserial >= 3.3 and PyYAML >= 5.1 (both pulled in by the
[gui]extra) - Tkinter — bundled with the standard Python installers on Windows and
macOS. On Linux, install it from your package manager
(Debian/Ubuntu:
sudo apt install python3-tk).
From PyPI:
pip install serial-tcp-clients-guiThe GUI is its own package; it pulls in the CLI/backend package
(serial-tcp-clients) and PyYAML automatically.
From source (recommended for development) — Windows:
git clone https://github.com/maslovw/serial_tcp_clients.git
cd serial_tcp_clients
python -m venv .venv
.venv\Scripts\activate
pip install -e . -e guiFrom source — Linux / macOS:
git clone https://github.com/maslovw/serial_tcp_clients.git
cd serial_tcp_clients
python3 -m venv .venv
source .venv/bin/activate
pip install -e . -e guiStandalone Windows executable (no Python needed on the target machine):
deploy\build-gui.batThis uses PyInstaller to produce a single windowed binary serial-tcp-gui.exe
in the repository root. It builds in a throwaway virtualenv, so it does not
touch your working .venv. Pass an explicit interpreter if python is not on
your PATH: deploy\build-gui.bat C:\Python310\python.exe.
With the package installed (console script on PATH):
serial-tcp-gui # loads ./serialtcp_ports.yaml if present
serial-tcp-gui ports.yaml # load a specific configAs a module (works without the console script on PATH):
python -m serialtcp_gui ports.yamlFrom a source venv on Windows, or the standalone build:
.venv\Scripts\serial-tcp-gui.exe ports.yaml
serial-tcp-gui.exe ports.yamlIf no config path is given, the app uses ./serialtcp_ports.yaml. Any mapping
you Add/Edit/Remove in the GUI is saved back to that file.
A YAML file with a ports: list; each entry binds one serial device to one TCP
listen port. Only device and tcp_port are required — everything else has
sensible defaults.
ports:
- name: COM103 # optional label (defaults to the device name)
device: COM103 # COM103 on Windows, /dev/ttyUSB0 on Linux
tcp_port: 5000 # TCP port that clients connect to
baudrate: 921600
parity: N # one of N E O S M
xonxoff: false # software flow control
char_mode: false # send characters one at a time
char_delay: 0.0 # seconds between characters
wait_echo: 0.0 # seconds to wait for echo per character
line_ending: CRLF # console send newline: CRLF | LF | CR | none
log_file: '' # path to log all serial activity ('' = off)
allow_remote: false # false = listen on 127.0.0.1 only; true = 0.0.0.0
autostart: true # start listening as soon as the GUI opensBy default a mapping listens on 127.0.0.1 (localhost only), so the serial
console is not exposed on the network. Set allow_remote: true (or tick
Allow remote connections in the Add/Edit dialog) to bind 0.0.0.0 and accept
connections from other machines.
A ready-to-edit example lives in ports.example.yaml.
-
Start / Stop a port from its card or the detail panel; Start all and Stop all are in the top bar.
-
+ Add serial → TCP port (top bar or the dashed list footer) opens a dialog to choose the serial device, baudrate, parity, flow/char options and the TCP listen port. Edit changes a mapping; Remove deletes a stopped one.
-
Connect any TCP client to the listen port to talk to the device, e.g.:
telnet localhost 5000
or PuTTY (connection type Raw or Telnet, host
localhost, port5000), ornc localhost 5000. Several clients can share one serial device at once. -
Console — the live log timestamps each line
[HH:MM:SS:MSEC], renders ANSI colours and splits CR/CRLF/LF lines; scroll back through history with the scrollbar or mouse wheel. The header has copy (the selection, or the whole console) and clear buttons. The input row sends what you type; the dropdown next to it picks the appended line ending (CRLF/LF/CR/none), which is saved to the config. -
Terminal as a client — the serial port is normally open only while a TCP client is connected. Click Connect in the console input row to attach the GUI itself as a client (opening the serial port) so you can send and receive in the integrated terminal with no external client connected; Disconnect releases it (and closes the port if nothing else is using it).
-
Logging — click log in the console header (or set
log_filein the config / dialog) to record all serial activity to a file. Each line is stamped[dd.mm.YY HH:MM:SS:MSEC].
