通过netcat将行发送到Python的问题

时间:2016-09-22 01:51:10

标签: python sockets

我正在将程序的stdout传递给netcat:nc -u localhost 50000。收听UDP 50000是一个Python程序,可以执行以下操作:

  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

我总会得到几行,但程序会挂起print '1'。当我运行行生成程序时,输出是每秒一行到标准输入。这是怎么回事?

编辑,以防它以某种方式相关:生成行的程序在docker中运行(与--net="host"一起运行,服务器(接受行)在运行docker的主机上.Docker正在发送它超过127.0.0.1。

另一个编辑:收到SOCK_BUFSZ字节时似乎停止接受输入。它不是回收缓冲区吗?

更新:这似乎是Docker的一个问题。它适用于localhost,但不适用于容器。我有连接(我可以ping服务器,第一个数据突发通过)。

1 个答案:

答案 0 :(得分:1)

这个Python脚本对我有用:

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

我使用这个bash脚本发送行:

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

在睡眠中浪费时间的时候,我没有看到将套接字设置为非阻塞的重点。

来自a commenthorse_hair后,我把服务器放在一个帖子中:

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()

一切仍然有效。