Using netcat to send a UDP packet without binding
Asked Answered
C

2

8

I am trying to use netcat to simulate a NAT traversal protocol.

I have one instance that is listening for UDP packets on port 6666, as so:

nc -ul 6666

In another terminal window, I am trying to periodically send a UDP packet from port 6666 (to open the return path on my router. this would be in a script that repeats every 20 seconds to re-open the port)

nc -u -p6666 mypinghost.com 4444

The problem is netcat fails on this ping call with the message:

nc: bind failed: Address already in use

Which implies that the listener having bound to port 6666 is blocking another process from sending from that port, or possibly that netcat is trying to bind to 6666 to listen.

Is this just how netcat is written, or can I tickle it some way to let me send a packet without binding to the port to listen?

Contango answered 8/7, 2012 at 22:0 Comment(0)
C
9

nc -ul 6666

Listen at UDP port 6666.

nc -u -p6666 mypinghost.com 4444

Using UDP port 6666 as the source port, send to mypinghost:4444.

nc: bind failed: Address already in use

That would be on the second netcat invocation, where 6666 is already in use by the first one.

Which implies that the listener having bound to port 6666 is blocking another process from sending from that port

Correct.

or possibly that netcat is trying to bind to 6666 to listen.

And definitely that. You told it to do that, so it did it.

What you are trying to do is impossible between two processes in the same host. Only one process can use a specific local UDP port at a time, unless you use SO_REUSEADDRESS, which netcat doesn't appear to implement.

As the other poster has suggested, the solution lies in using a single process.

Coats answered 10/7, 2012 at 0:0 Comment(4)
I'm having this same problem, and I figured that SO_REUSEADDRESS avoids that error. But then the return messages don't get picked up by the listening process -- unless I start it after the sending process binds the port. My understanding is that option is used for "multicast" (which I don't think is my case), but is there way to use it so the messages sent to port 6666 go to the process that wants to receive them, rather than the most recent process to bind the port?Armhole
@Armhole The messages should go to all processes that are receiving from that port.Coats
By "processes that are receiving", do you mean those that are bound to it, or those that call recvfrom ? As it happens, UDP datagrams seem to be reliably picked up only by the most recent process to bind. Even if that process never calls recvfrom, it still stops the other from receiving anything. But this comment discussion is getting crowded so I'll ask a separate question and include my code, unless you can think of something simple that I'm probably missing. ;-)Armhole
@Armhole It means processes that are bound to that port. They don't have to be currently calling recv(), there is a socket receive buffer for that.Coats
P
2

I do not believe you can use netcat in that way. I would recommend writing a simple Python script that does both the sending and receiving tasks in one process. That way you can hold that port exclusively and still accomplish both tasks.

Polysyndeton answered 9/7, 2012 at 23:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.