# # socket-send.pl -- network utility to send stuff to the CogServer. # # Implements simplistic `netcat` type functionality in plain-old TCP # sockets. Earlier versions just used netcat directly; this was OK but... # it bottlnecked and lead to poor performance, especially when the # cogserver could respond quickly. Forking a new netcat each time # was remarkably inefficient, with massive slowdowns. See the mailing # list circa 2017(?) for details. # use Socket; # Takes three arguments: server, port and string to send. sub send_nowait { my $server = $_[0]; my $port = $_[1]; my $msg = $_[2]; socket(SOCKET, PF_INET, SOCK_STREAM, (getprotobyname('tcp'))[2]) or die "Can't create a socket $!\n"; # If the cogserver is really slow (e.g. if it is being debugged) # the connet will fail (a max of 140 pending connects are possible # without changing ulimit). This is very rare. If it fails, we retry. my $rc = connect(SOCKET, pack_sockaddr_in($port, inet_aton($server))); if (not $rc) { print "Couldn't connect to port $port! Retrying...\n"; my $i=0; sleep 1; while ($i<100 and not $rc) { $i++; $rc = connect(SOCKET, pack_sockaddr_in($port, inet_aton($server))); if (not $rc) { print "Retry $i\n"; sleep 1; } } ($i<100) or die "Fatal Error: Unable to connect to port $port\n"; } # Two dots: one to exit scheme, one to exit cogserver prompt. print SOCKET "$msg\n.\n.\n"; # Close socket immediately. Do NOT wait for any replies!! close SOCKET; } # Hang, until the cogserver is idle enough to allow us to connect. # Basically, the cogserver stops responding until it's work queues # are empty enough to allow a response. # # Takes two arguments: server and port. sub ping_flush { my $server = $_[0]; my $port = $_[1]; socket(SOCKET, PF_INET, SOCK_STREAM, (getprotobyname('tcp'))[2]) or die "Can't create a socket $!\n"; my $rc = connect(SOCKET, pack_sockaddr_in($port, inet_aton($server))); if ($rc) { # One dot: exit cogserver prompt. print SOCKET ".\n"; shutdown(SOCKET, 1); # Spin until EOF on the socket my $foo = ""; my $rrc = read SOCKET, $foo, 500; while ($rrc) { $rrc = read SOCKET, $foo, 500; } # OK, a second shutdown returns error and sets $! to # `Transport endpoint is not connected` so that's really weird. # and a close SOCKET just flat-out crashes! # Whatever. The script exits, the kernel cleans up. } }