Receiving multiple files at once in Netcat without overwriting last file

0

1 machine listens(linux), while multiple clients(windows) send files to it on one and the same listening port. Netcat receives the files serially with the -k tag.

Listening machine: 
  nc -lp PORT -k > fileX
Clients: 
  nc IP PORT < file??

What I want is to receive multiple files from multiple sources WITHOUT them overwriting each other.

Please look at the previous commands. The listener machine with always write output to fileX, thus overwriting the previous client's file.

I want to somehow be able to change the output filename for every different client. Can the client send the string "file10" over netcat somehow and so tell the listener to output to > file10 ?

Thank you.

EDIT: Came up with an idea:

This is automated via script:

  1. Firstly, listener sets output file to file.txt. (nc -lp PORT > file.txt)

  2. Client sends string (eg "file123") via netcat. (This will be the filename for the file that will be sent in the future.)

  3. Listener writes to file.txt, then reads file.txt, and starts a new netcat listener with output file > file123

  4. Finally, client sends data.

MyWays

Posted 2018-10-21T12:38:34.263

Reputation: 157

Answers

0

This other answer discusses the point of having your custom protocol/setup. I won't repeat it. I assume your own solution is what you want.

nc -k is not the best tool to receive "multiple files from multiple sources" because it will listen for another connection only after the current one terminates. This means it will receive multiple files but one by one, not in parallel. Your "multiple sources" will block one another.

socat with reuseaddr and fork may be better.

As a proof of concept let's create (in a quick and dirty way) our custom protocol. A file will be transferred as a stream that consists of:

  1. filename or path to use on the receiving side (without newlines);
  2. single newline (\n, LF, 0x0a) as a separator;
  3. binary data;
  4. EOF.

This is the receiving command:

socat TCP-LISTEN:50011,reuseaddr,fork SYSTEM:'read -r f && cat >"$f"'

(Edit) This is universal receiving command that strips trailing \r (if any) from filename (useful for working with Windows clients not entirely protocol-compliant):

socat TCP-LISTEN:50011,reuseaddr,fork SYSTEM:'read -r f && f="${f%$(printf "\r")}" && cat >"$f"'

(Edit ends here).

To send a file:

(echo "The new name.foo" && cat "./the file to send.bar") > /dev/tcp/192.168.22.33/50011

Notes:

  • 50011 is a TCP port number, you can choose your own;
  • 192.168.22.33 is the address of the server, change it to match your setup;
  • I used /dev/tcp/…/… syntax that works in Bash, pipe to nc if you want/need;
  • filename collisions are still the issue, you need some scripted logic (instead of plain cat) to resolve them;
  • SYSTEM has its limitations (see man socat); instead of passing some large script body to it, write the script to a file and run the file; you can also investigate EXEC;
  • our protocol (being quick and dirty) doesn't provide any way for a server to report errors (if any) or success to a client.

I tested this with Debian receiver and Ubuntu sender. At one moment three different connections were transferring three different files from two different IP addresses. After all the transfers completed, md5sum was used to verify if the copies were (most likely) the same as originals; they were.

Kamil Maciorowski

Posted 2018-10-21T12:38:34.263

Reputation: 38 429

Nice. How do I send the file if the client is windows? I tried in powershell.. This is how far I got. $file=Get-Content ./somefile; echo "filename10"$file | ./Netcat32 IP PORT. On the linux machine i get a file called " 'filename10'$'\r' " (without double quotes). The file contents are correct but the file name is off. – MyWays – 2018-10-21T19:08:23.160

@MyWays I cannot help you with this PowerShell code (I'm a Linux guy, I have never worked with PowerShell), but the issue looks like being caused by different line endings in Windows and in Unix.

– Kamil Maciorowski – 2018-10-21T19:12:48.153

@MyWays Although proper code between read and cat in Linux can fix this. Give me few minutes. – Kamil Maciorowski – 2018-10-21T19:15:09.793

@MyWays My answer now addresses this. – Kamil Maciorowski – 2018-10-21T19:30:52.180

this is some wizardry right here. – MyWays – 2018-10-21T19:32:12.417

Sorry to hijack, since there's no PM option on this forum apparently.. but how to close the connection on the client after the file is done transferring? I got netcat version 1.11 on windows that has no -q parameter like nc does on linux. – MyWays – 2018-10-21T19:40:27.773

Let us continue this discussion in chat.

– Kamil Maciorowski – 2018-10-21T19:41:28.783

0

No, ordinary netcat has no such special commands. It doesn't interpret its input, and really it doesn't even know that its input/output is a file: the redirection is done by you shell and netcat doesn't bother looking.

So you need an additional program which does interpret received input and opens the output files on its own. In the end, you would practically reinvent tar. (Or cpio, or a dozen other similar formats.)

[client] tar -cf - fileXYZ | nc <ip> <port>
[server] nc -lp <port> | tar -xvf -

There are Windows builds of GNU tar, and Win10 has recently started including bsdtar. If neither is available, you'll have to create some protocol of your own – e.g. send the filename as the first line, followed by data; you'll need to write custom code for the sender and for the receiver.

Grouping multiple commands in parentheses as a single pipeline unit will help:

[client] (echo fileXYZ && type fileXYZ) | nc <ip> <port>
[server] nc -lp <port> | (read name; name=${name##*/}; name=${name%$'\r'}; cat > "$name")

But instead, I would set up Samba on the Linux machine and configure a public share, so that clients could simply copy fileXYZ \\<ip>\incoming\fileXYZ.

user1686

Posted 2018-10-21T12:38:34.263

Reputation: 283 655

"…create some protocol of your own" – The OP's nick is MyWays. :D – Kamil Maciorowski – 2018-10-21T14:17:52.900

@grawity Thanks for the answer. I'll try. Please read my answer again as I've added an idea and tell me what do you think? – MyWays – 2018-10-21T14:18:10.697

@KamilMaciorowski Haha, what's that supposed to mean? – MyWays – 2018-10-21T14:18:57.213

@MyWays You may reinvent tar your way. – Kamil Maciorowski – 2018-10-21T14:19:48.413

its my way or the tarway, jk. Is my edit a good idea? – MyWays – 2018-10-21T14:20:55.827