50

I'm using something like this to send file from one computer to another:

To serve file (on computer A):

cat something.zip | nc -l -p 1234

To receive file (on computer B):

netcat server.ip.here. 1234 > something.zip

My question is... can I do the opposite? Let's say I have file on computer B and I want to send it to A but not the way I wrote above, but by making computer that's supposed to receive file (A) be 'listening' server and connect computer that's 'sending' file (B) to server and send the file? Is it possible? I think it might be but I'm not sure how to do this.

In case my above explanation is messed up: How do I send file TO 'server' instead of serving the file on server and then taking it FROM it (like I did above)?

1

6 Answers 6

78

On your server (A):

nc -l -p 1234 -q 1 > something.zip < /dev/null
On your "sender client" (B):
cat something.zip | netcat server.ip.here 1234

9
  • Yeah, I thought that I'll have to switch sides somehow but I wasn't sure how :). Thanks, it works!
    – Phil
    Jan 21, 2010 at 4:23
  • That's a cute netcat trick. Jan 21, 2010 at 16:09
  • 10
    why the < /dev/null part? Nov 27, 2012 at 11:17
  • 14
    Because netcat both reads stdin and writes stdout simultaneously, sending anything read from stdin out to the network and printing anything received from the network on stdout. The </dev/null ensures that, when the received file has completed, netcat doesn't sit there indefinitely waiting for input from the console (which it shouldn't be reading anyway!) and also ensures that it doesn't gobble up any input that may be available from the terminal, such as you typing the next command you wanted to run.
    – martinwguy
    Jan 4, 2013 at 7:18
  • 6
    if you have pv, I would suggest operating the "server client" as pv soemthing.zip | ..., that will display the progress of the file read going into the pipe. Mar 21, 2017 at 15:54
9

As a note, if you want to also preserve file permissions, ownership and timestamps, we use tar with netcat to do transfers of directories and files.

On receiving system:

nc -l -p 12345 -q 1 | tar xz -C /path/to/root/of/tree

From sending system:

tar czf - ./directory_tree_to_xfer | nc <host name or IP address of receiving system> 12345 

Hope that helps.

4
  • 1
    Good addition to the answer, but please leave it as a comment and not as a separate answer.
    – agtoever
    Feb 27, 2015 at 0:33
  • 4
    Couldn't add a comment above due to lack of Rep points on this sub-board, so I had to offer it as an answer, though apparently, you are allowed to comment on your own answers.
    – B.Kaatz
    Mar 12, 2015 at 23:30
  • Doesn't work on MacOS receiver. -q and -l cause errors.
    – John Smith
    Nov 18, 2023 at 7:16
  • Tried it without -q and -p (used -l 12345) and is seemed to work on the receiving end. Debian sending end failed abysmally with Connection timed out tar: -: Cannot write: Broken pipe tar: Child returned status 141 tar: Error is not recoverable: exiting now I know the connection is fine though because I'm ssh'd into it right now. Something is wrong with this "answer". I guess this is the part where I spend 2 hours trying nonworking SE answers in order to avoid the 1 hour it would take to copy the file over the network with sftp...
    – John Smith
    Nov 18, 2023 at 7:25
7

Computer A: nc -l -p 1234 > filename.txt

Computer B: nc server.com 1234 < filename.txt

Should work too ;)

1

Init the target listening to the port. AKA receiver end

nc -vl 44444 > pick_desired_name_for_received_file

Send the file to the target. AKA sender end

nc -n TargetIP 44444 < /path/to/file/you/want/to/send

read more https://www.maketecheasier.com/netcat-transfer-files-between-linux-computers/ https://gist.github.com/A1vinSmith/78786df7899a840ec43c5ddecb6a4740

1

I cooked everything for you. Keep it handy for regular use case.
Make sure you change IP and port in this script.

There are 3 modes.
1. direct file transfer
2. compressed file transfer
3. folder transfer

receivefile() {
    [ $# -lt 1 ] && echo '$0 <file> <port>' && return 1
    local file=$1
    local port=${18080:-2}
    md5sum $file
    nc -v -l 0.0.0.0 -p $port > $file
}

sendfile() {
    [ $# -lt 1 ] && echo '$0 <file> <server> <port>' && return 1
    local file=$1
    local server=${115.98.2.1:-2}
    local port=${18080:-3}
    md5sum $file
    nc -c $server $port < $file
}

receivefilecompressed() {
    [ $# -lt 1 ] && echo '$0 <file> <port>' && return 1
    local file=$1
    local port=${18080:-2}
    md5sum $file
    nc -v -l 0.0.0.0 -p $port | gunzip > $file
}

sendfilecompressed() {
    [ $# -lt 1 ] && echo '$0 <file> <server> <port>' && return 1
    local file=$1
    local server=${115.98.2.1:-2}
    local port=${18080:-3}
    md5sum $file
    gzip -c $file | nc -c $server $port
}

receivefolder() {
    local port=${18080:-1}
    nc -v -l 0.0.0.0 -p $port | tar zxv
}

sendfolder() {
    [ $# -lt 1 ] && echo '$0 <folder> <server> <port>' && return 1
    local folder=$1
    local server=${115.98.2.1:-2}
    local port=${18080:-3}
    tar czp $folder | nc -c $server $port
}
0

Start another instance of netcat on computer B. Just do what you did on computer A, but serve it from B. Give the new server a new port.

4
  • I don't want to do the same, I want to change commands to something else (i'm not sure if it's possible)... look at bold text in my question. What I mean is that I don't want to serve from B. I want A to be server listening for input... and then I want to send file contents from non-listening B to listening A.
    – Phil
    Jan 20, 2010 at 5:51
  • That's not how netcat works. Jan 20, 2010 at 15:14
  • 1
    As you can see from accepted answer - yes, that's how netcat can work too.
    – Phil
    Jan 21, 2010 at 4:24
  • You're right. I learn something new every day! Jan 21, 2010 at 16:10

You must log in to answer this question.

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