I spent several more hours on this topic today and here report some progress. I know this sounds very obscure, but something seriously cool may come of this. The following shows a hack that mostly works, to allow Mathematica to do 2-way communication with a netcat session on a local or remote machine. The hack is that I had to set up a stream that used netcat itself. So this is not as portable across platforms as I would like, and is not reading and writing directly to ports. To improve reliability, I have to open and close streams on each invocation, which must be hurting speed.
rnc::usage =
"rnc[machine,port] reads a string from a netcat session running on \
a local or remote machine on the specified port. Start the netcat \
session with $ nc -l -k <port>.";
wnc::usage = [/size]
"wnc[string,machine,port] writes a string to a netcat session \
running on a local or remote machine on the specified port. Start the \
netcat session with $ nc -l -k <port>.";
Clear[rnc, wnc];[/size]
rnc[machinename_String: "localhost", port_Integer: 1234] :=
Module[{istr},
Map[Close, Complement[Streams[], Take[Streams[], 2]]] ;
istr = OpenRead["!nc " <> machinename <> " " <> ToString[port]];
Read[istr, Record]]
wnc[text_String: "hello", machinename_String: "localhost", [/size]
port_Integer: 1234] := Module[{ostr},
Map[Close, Complement[Streams[], Take[Streams[], 2]]] ;
ostr = OpenWrite["!nc " <> machinename <> " " <> ToString[port]] ;
Write[ostr, OutputForm[text]]]
If you start netcat on a remote (Mac or Linux) machine, using the Terminal, for example on a computer named "HAL9000" with:
$ nc -l -k 1234
and you execute the Mathematica command defined above, on your local machine:
wnc["Hello Hal", "HAL9000", 1234]
then "Hello Hal" appears on the remote machine. And If you type "Hello Dave" followed by carriage return, in the remote netcat session, you can retrieve this string with:
rnc["HAL9000", 1234]
The absolute timing of these transactions is milliseconds, but quite variable, and when using my flaky WiFi network, they are not 100% reliable. Since my goal here is to control a LinuxCNC process, which is in turn controlling a CNC machine, from Mathematica, these issues need attention next. Still would like to know how to do this using pure Wolfram Language commands.