11

This comand (serial port redirector) accepts a single connection on TCP:11313 :

socat PTY,link=/dev/ttyV1,echo=0,raw,unlink-close=0 TCP-LISTEN:11313,forever,reuseaddr

However when the connection is lost, the above socat process is killed and the client is not able to connect.

I can solve this by adding fork option at the end of the above command. But then multiple clients will be able to connect. But I want to accept only one connection.

Any ideas how to achieve this?

DarkLeafyGreen
  • 69,338
  • 131
  • 383
  • 601
  • May be ser2net (http://ser2net.sourceforge.net/) is what you need? – Maquefel Jan 22 '15 at 10:45
  • @Maquefel do you have experience with ser2net. For me it looks like they are doing quite the same. – DarkLeafyGreen Jan 22 '15 at 11:02
  • 1
    I have - ser2net is a specialized thing it can't do most things like socat, it designed especially for forwarding serial to ethernet. But it behaves exactly as you want - one port - one connection, doesn't exit when connection is closed and notifies new incoming connection about port in use. – Maquefel Jan 22 '15 at 12:02
  • @Maquefel I def going to check this out, thank you! – DarkLeafyGreen Jan 23 '15 at 09:01

1 Answers1

11

You can limit the number of children with the max-children option:

LISTEN option group, options specific to listening sockets

max-children= Limits the number of concurrent child processes [int]. Default is no limit.

With this you can limit the number of clients that can interact with the PTY to one, but won't prevent others from connecting. Others will simply queue until the first connection is closed. If you want to prevent that, I'd suggest to just wrap the socat call in a while true; do ..; done loop:

while true; do
  socat PTY,link=/dev/ttyV1,echo=0,raw,unlink-close=0 TCP-LISTEN:11313,forever,reuseaddr
done
Phillip
  • 13,448
  • 29
  • 41
  • 2
    better to use `while sleep 1; do .. ; done loop`, because some shells cannot handle correctly the SIGINT signal in this loop, and you may or may not be able to interrupt the loop correctly – Gabor Garami Jan 22 '15 at 09:35
  • 1
    Yes. I updated the answer with the exact command. The snippet runs socat in an infinite loop, restarting it right away whenever it quits. If you never worked with them, consider Gabor's hint and replace `true` with `sleep 1` for starters. – Phillip Jan 22 '15 at 11:36
  • You can also add `backlog=0` to prevent new connections from queing up when there is already one active. One caveat, though: This seems to prevent *complete* connections from queuing up, but (contrary to what `listen(2)` suggests) does not return a "connection refused", but just leaves new clients waiting for the connection to complete (i.e. wait for the SYNACK, I suspect), causing them to eventually timeout. Not entirely perfect, but it does ensure that additional connections do not actually succeed (at least not until to first connection terminates). – Matthijs Kooijman Jul 20 '21 at 08:15
  • Hm, seems there is a sort of "off-by-one" in the `backlog` option, specifying `backlog=0` will allow *one* additional connection to succeed, waiting for the first connection to terminate (and `backlog=1` allows *two* to succeed). Not sure if this is how Linux `listen(2)` works, or something in socat, but it does kind of make the `backlog` option useless in this context. – Matthijs Kooijman Jul 20 '21 at 08:26