3

I have 4 programs, will be increased in the future, these programs have to connect to the same ip:port to send and receive messages at the same time.

Until now I have the socket opened, I also would like to keep the connection alive between the programs and the server.

#!/bin/sh
nc -lvk 88.109.110.161 100 > port100.txt 2>&1

2 Answers 2

8

nc does not handle multiple connected clients in parallel and is the wrong tool for this job. There are quite a few right tools for this job, including:

  1. Bernstein tcpserver (original or djbwares) or Hoffman tcpserver:
    tcpserver -v -R -H -l 0 88.109.110.161 100 sh -c 'exec cat 1>&2' 2>&1 |
    cyclog port100/
  2. my tcpserver shim:
    tcpserver -v 88.109.110.161 100 sh -c 'exec cat 1>&2' 2>&1 |
    cyclog port100/
  3. my UCSPI-TCP tools:
    tcp-socket-listen 88.109.110.161 100 tcp-socket-accept --verbose sh -c 'exec cat 1>&2' 2>&1 |
    cyclog port100/
  4. Bercot s6-tcpserver4:
    s6-tcpserver4 -v 2 88.109.110.161 100 sh -c 'exec cat 1>&2' 2>&1 |
    cyclog port100/
  5. Bercot s6-networking tools:
    s6-tcpserver4-socketbinder 88.109.110.161 100 s6-tcpserver4d -v 2 sh -c 'exec cat 1>&2' 2>&1 |
    cyclog port100/
  6. Pape tcpsvd:
    tcpsvd -v 88.109.110.161 100 sh -c 'exec cat 1>&2' 2>&1 |
    cyclog port100/
  7. Sampson onenetd:
    onenetd -v 88.109.110.161 100 sh -c 'exec cat 1>&2' 2>&1 |
    cyclog port100/

And one can substitute multilog, s6-log, svlogd, or tinylog for cyclog.

Further reading

2
  • One can also consider use a load balancing proxy like haproxy in front of the servelets to direct tcp streams based on some filterable information or in a load balance configuration with maxconn = 1
    – crasic
    Commented Apr 21, 2019 at 20:24
  • I will test them and will let you know how it goes Commented Apr 22, 2019 at 13:06
0

It's a real pity that there's no standard/readily available tool for such basic task, but if you're not on some embedded system and have some scripting language like perl or python available, you can quickly put something together:

tcpsrv:

#! /usr/bin/perl
use strict;
use IO::Socket::INET6;
die "usage: $0 host:port { shell_cmd | cmd args ... }\n" unless @ARGV >= 2;
my $h = shift;
my $s=new IO::Socket::INET6(ReusePort=>1, Listen=>6, LocalAddr=>$h)
        or die "IO::Socket::INET($h): $!";
warn "listening on ", $s->sockhost, "/", $s->sockport, "\n";
$SIG{CHLD} = sub { use POSIX qw(WNOHANG); 1 while waitpid(-1, WNOHANG) > 0 };
while(1){
        my $a = $s->accept or do { die "accept: $!" unless $!{EINTR}; next };
        warn "connection from ", $a->peerhost, "/", $a->peerport, "\n";
        die unless defined(my $p = fork);
        close($a), next if $p;
        open STDIN, "<&", $a and open STDOUT, ">&", $a or die "dup: $!";
        close $s and close $a or die "close: $!";
        exec(@ARGV); die "exec @ARGV: $!";
}

Usage: tcpsrv host:port cmd

This will listen on host:port, and anytime a client connects to host:host, it will fork & exec cmd with its stdin and stdout redirected from/to the connection:

tcpsrv :9999 ls .
tcpsrv 127.0.0.1:7000 uptime
tcpsrv [::]:7000 uptime
tcpsrv 88.109.110.161:2000 'cat > port2000.txt'
1
  • Never worked with perl, but I will do the attempt, thanks Commented Apr 22, 2019 at 13:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .