"Connection refused" when I try to send a UDP packet with netcat on an embedded-linux board

I’m trying to send a binary packet to a local process, via netcat (nc), like this:

nc -w 1 -u localhost 10000 < my_binary_packet.bin

The output is:

read(net): Connection refused

Anyone know what’s going on?

I get the same result with nc -w 1 -u 127.0.0.1 10000 < my_binary_packet.bin

Asked By: Gabriel Staples

||

Summary

If your listener is bound to a particular IP (such as 192.168.0.10) and port (such as 10000) instead of to IP INADDR_ANY (Internet Namespace Address Any, which means it listens to all interfaces / IP addresses), do this instead to specify the correct IP:

# with netcat
nc -w 1 -u 192.168.0.10 10000 < my_binary_packet.bin

# OR (same thing), with socat
socat udp:192.168.0.10:10000 - < my_binary_packet.bin

Details

Ok so I figured it out!

I wrote the local listener process (UDP "server/listener") I was trying to send the binary packet to (from a UDP "client/sender"), and I had bound that socket to a particular IP address, 192.168.0.10, instead of to the "catch-all" IP address INADDR_ANY. Binding to that particular IP address means that my listener process is NOT listening to localhost (127.0.0.1), so those packets were getting rejected! I didn’t know that you could send a process running on the same PC some data by using anything other than localhost or 127.0.0.1, but apparently you can.

So, this works instead:

nc -w 1 -u 192.168.0.10 10000 < my_binary_packet.bin

The timeout/wait period of 1 second (-w 1), however, doesn’t seem to do anything–I’m not sure why. It just sits there after it sends the packet, and I have to Ctrl + C the nc process after it sends, if I want to send it again. That doesn’t really matter though–the point is: it works!

I also carefully read the comments under my question, so here’s some more information for anyone wondering:

The equivalent socat command is this (don’t forget the - in the command!):

socat udp:192.168.0.10:10000 - < my_binary_packet.bin

Also, here are my versions of netcat and socat on the embedded Linux board.

# nc -h
GNU netcat 0.7.1, a rewrite of the famous networking tool.

# nc -V
netcat (The GNU Netcat) 0.7.1
Copyright (C) 2002 - 2003  Giovanni Giacobbi

# socat -V
socat by Gerhard Rieger and contributors - see www.dest-unreach.org
socat version 1.7.3.4 on May  6 2022 17:55:04

Going further

How to build a binary packet in C or C++ to send via netcat or socat

Lastly, for anyone wondering, the way I wrote the binary packet my_binary_packet.bin is by simply writing some C code to write a packed struct to a file using the Linux write() command.

Writing the packet to a binary file like this allows for easy testing via netcat or socat, which is what drove me to ask the question when it didn’t work.

Be sure to set file permissions while opening the file. Ex:

int file = open("my_binary_packet.bin", O_WRONLY | O_CREAT, 0644);

And here is what the struct definition looks like. The my_binary_packet.bin file literally just contains a byte-for-byte copy of this struct inside that binary packet, after I set particular, required values for each member of the struct:

struct __attribute__((__packed__)) my_packet {
    bool flag1;
    bool flag2;
    bool flag3;
};

Full code to open the file, create the packet, and write the binary packet to a file might look like this:

typedef struct __attribute__((__packed__)) my_packet_s {
    bool flag1;
    bool flag2;
    bool flag3;
} my_packet_t;
    
int file = open("my_binary_packet.bin", O_WRONLY | O_CREAT, 0644);
if (file == -1)
{
    printf("Failed to open. errno = %i: %sn", errno, strerror(errno));
    return;
}

my_packet_t my_packet = 
{
    .flag1 = true,
    .flag2 = true,
    .flag3 = true,
};

ssize_t num_bytes_written = write(file, &my_packet, sizeof(my_packet));
if (num_bytes_written == -1)
{
    printf("Failed to write. errno = %i: %sn", errno, strerror(errno));
    return;
}

int retcode = close(file);
if (retcode == -1)
{
    printf("Failed to close. errno = %i: %sn", errno, strerror(errno));
    return;
}

For anyone who wants to learn how to program Berkeley sockets in C or C++…

I wrote this really thorough demo in my eRCaGuy_hello_world repo. This server code is what my UDP listener process is based on:

  1. socket__geeksforgeeks_udp_server_GS_edit_GREAT.c
  2. socket__geeksforgeeks_udp_client_GS_edit_GREAT.c

References

  1. The comments under my question.
  2. There are many versions of netcat: Netcat – How to listen on a TCP port using IPv6 address?
  3. This answer, and my comment here: Error receiving in UDP: Connection refused

See also

  1. My answer on General netcat (nc) usage instructions, including setting the IP address to bind to when receiving, or to send to when sending
Answered By: Gabriel Staples
Categories: Answers Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.