1

I am piping a program's stdout to netcat: nc -u localhost 50000. Listening on UDP 50000 is a Python program that does something like this:

  lstsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  lstsock.setblocking(0)

  while True:
        print '1'
        try:
            tmp = lstsock.recv(SOCK_BUFSZ)
        except socket.error, e:
            if e.args[0] == errno.EWOULDBLOCK:
                sleep(.5)
                continue
            else:
                print("Socket error: {}".format(e))
                return
        print tmp

I'll always get a few lines, but then the program hangs on print '1'. When I run the line-generating program, the output is a line to stdin about every second. What's going on here?

Edit, in case it's somehow related: The program producing lines is in docker (run with --net="host", and the server (accepting lines) is on the host running docker. Docker is sending it over 127.0.0.1.

Another edit: It seems to stop accepting input when SOCK_BUFSZ bytes were received. It's not recycling the buffer?

Update: this seems to be an issue with Docker. It works on localhost, but not from the container. I have connectivity (I can ping the server, and the first burst of data gets through).

2
  • May I ask you to show us your netcat script? Commented Sep 22, 2016 at 5:01
  • @DavidCullen - ./command | nc -u localhost 50000 Commented Sep 22, 2016 at 9:09

1 Answer 1

1

This Python script worked for me:

import socket

lstsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
lstsock.bind(('127.0.0.1', 50000))

SOCK_BUFSZ = 4096
counter = 1
while True:
    print "counter = %s" % counter
    counter += 1
    data, addr = lstsock.recvfrom(SOCK_BUFSZ)
    print data

I used this bash script to send lines:

while true ;
do
    echo "Running..."
    echo -n "hello" | nc -w 0 -u "127.0.0.1" 50000
    sleep 1
done

I didn't see the point of setting the socket to be non-blocking when time was wasted in a sleep.

After a comment from horse_hair, I put put the server in a thread:

import socket
import threading
import time

SOCK_BUFSZ = 4096

def udp_server(quit_flag):
    udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    udp_sock.bind(('127.0.0.1', 50000))
    counter = 1
    while not quit_flag.is_set():
        print "counter = %s" % counter
        counter += 1
        data, addr = udp_sock.recvfrom(SOCK_BUFSZ)
        print data

def main():
    quit_flag = threading.Event()
    udp_thread = threading.Thread(target=udp_server, args=(quit_flag,))
    udp_thread.daemon = True
    udp_thread.start()
    try:
        while True:
            time.sleep(1.0)
    except KeyboardInterrupt:
        print "Exiting due to keyboard interrupt"
    quit_flag.set()
    udp_thread.join()

if __name__ == '__main__':
    main()

Everything still works.

Sign up to request clarification or add additional context in comments.

2 Comments

I get the first 'hello' then nothing for a long time, then a 'hello' again, repeat. Also, I get 'invalid wait time' when using the -w 0 option with netcat. The only difference is that my netcat is apparently different than yours, and I'm running through docker. Oh, and my receive loop is in a thread. Simply looping and printing 'hello' in the thread (without receiving from the network) works, so doesn't seem like there's delay in the run loop.
What version of netcat are you using? The nc on both OS X and Linux allows me to use -w 0. What is the output of ls -hl $(which nc)?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.