Bridge Serial-Ports over network
One side of the tcp connection needs to be listening on the port (the first one you launch), and the second side connects to it.
For the first side do:
socat tcp-listen:8080 pty,link=/dev/virtualport0
And for the second side do:
socat pty,link=/dev/virtualcom0 tcp:IP-of-other-machine:8080
Forget the netcat, you do not need it.
Create a virtual serial port connection over TCP
Try socat. Possible scenario:
socat pty,link=/dev/virtualcom0,raw tcp:192.168.254.254:8080&
socat creates TCP connection to 192.168.254.254:8080, so that everything, that will be written to /dev/virtualcom0 will be forwarded to 192.168.254.254:8080 and vice versa.
Another approach would be to use RFC2217 via ser2net on Linux sever side and RFC2217 driver on Windows side (for example http://www.hw-group.com/products/hw_vsp/index_en.html single port version). You can also try to get http://pyserial.sourceforge.net/ to work with ser2net.
Virtual Serial Port for Linux
You can use a pty ("pseudo-teletype", where a serial port is a "real teletype") for this. From one end, open /dev/ptyp5
, and then attach your program to /dev/ttyp5
; ttyp5
will act just like a serial port, but will send/receive everything it does via /dev/ptyp5.
If you really need it to talk to a file called /dev/ttys2
, then simply move your old /dev/ttys2
out of the way and make a symlink from ptyp5
to ttys2
.
Of course you can use some number other than ptyp5
. Perhaps pick one with a high number to avoid duplicates, since all your login terminals will also be using ptys.
Wikipedia has more about ptys: http://en.wikipedia.org/wiki/Pseudo_terminal
How to forward serial port data to a multiclient socket server in Python?
You need to implement some logic for when a network client disconnects.
You know a client has disconnected because you receive an empty response (b''
) from the socket. You're receiving data from network clients in NetToSerial
, here:
def run(self):
try:
while True:
data = self._socket.recv(1024)
serial_worker.write(data)
except (ConnectionAbortedError, ConnectionResetError):
print("NetToSerial client disconnection")
return
You need to check the value of data
, and if it's empty implement your disconnect logic:
- Close the associated socket.
- Exit the thread.
That might look like:
class NetToSerial(Thread):
"""socket->serial"""
serial_worker: serial.threaded.ReaderThread
def __init__(self, client_socket):
Thread.__init__(self)
self._socket = client_socket
def run(self):
try:
while True:
data = self._socket.recv(1024)
if not data:
break
serial_worker.write(data)
except (ConnectionAbortedError, ConnectionResetError):
print("NetToSerial client disconnection")
return
finally:
self._socket.close()
But that's only half the solution, because you're writing to this socket in your SerialToNet
class. You need to remove the socket from SerialToNet
sockets
array. You can have the class remove the socket in response to an exception when writing, like this:
class SerialToNet(serial.threaded.Protocol):
"""serial->socket"""
def __init__(self):
self.sockets: list[socket.socket] = []
def __call__(self):
return self
def data_received(self, data):
"""Forward data from Serial to IP client Sockets"""
for socket in self.sockets[:]:
try:
socket.sendall(data)
except OSError:
self.sockets.remove(socket)
Note that because it's not possible to remove an item from a list over which you're currently iterating, we are iterating over a copy of self.sockets
in the above code. This means we're free to remove sockets from self.sockets
from inside the loop.
With the above changes I believe your code will operate as you intend.
Not directly related to your question, but I'd like to make a comment about your code: as written, it allows multiple network clients to write to the serial port at the same time. That seems like a recipe for disaster and I cannot think of any situation in which that would make sense. You may want to reconsider that aspect of your code.
Related Topics
How Does Ltrace (Library Tracing Tool) Work
Would It Be Possible to Read Out Physical Keyboard Strokes in Node.Js
How to Use Ptrace(2) to Change Behaviour of Syscalls
Diff Files Inside of Zip Without Extracting It
How to Setup Cron Job on Amazon Linux Ami
Replace Forward Slash with Double Backslash Enclosed in Double Quotes
Srlua Makefile Error Lua.H No Such File or Directory
Driver Ch341 Usb Adapter Serial Port or Qserialport Not Works in Linux
Why Does The Solaris Assembler Generate Different Machine Code Than The Gnu Assembler Here
Bridge Serial-Ports Over Network
Running R in Batch Mode on Linux: Output Issues
Make Bash Differentiate Between Ctrl-<Letter> and Ctrl-Shift-<Letter>
How to Install Xclip on an Ec2 Instance
How to Print $ in Shell Script
Tickless Kernel, Isolcpus,Nohz_Full,And Rcu_Nocbs