希望在Python中模拟socat的功能

时间:2016-10-04 14:40:51

标签: python socketserver socat

我需要使用python将字符串发送到localhost上的特定端口。

我可以通过在命令行上使用socat来实现这一点:

cat <text file containing string to send> | socat stdin tcp-connect:127.0.0.1:55559

我不想将socat命令作为子命令运行,因此我想知道如何使用python模块实现这一功能。

我尝试使用套接字失败了。下面是我使用的一个脚本,它没有达到预期的效果。

    import socket
    HOST, PORT = "127.0.0.1", 55559
    jsonString = '{"name":"VideoStreamStatus","parameters":{"name":"video_0_0"}}'

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    try:
        # Connect to server and send data
        print "Attempting connection"
        sock.connect((HOST, PORT))
        print "Sending json string"
        sock.sendall(jsonString)
        print "String sent"

    finally:
        sock.close()

    print "Sent:     {}".format(jsonString)

python脚本正在执行而没有任何错误,但是对接收socat数据的进程没有任何影响。 Python脚本输出如下:

    Attempting connection
    Sending json string
    Sent:     {"name":"VideoStreamStatus","parameters":{"name":"video_0_0"}}

我是否在套接字脚本中出错了,或者我可以在Python中使用不同的方法?我很感激任何建议。感谢。

编辑:我尝试发送字符串的服务器是C ++程序的一部分,使用boost asio acceptor侦听特定地址和端口上的tcp连接。

3 个答案:

答案 0 :(得分:2)

原来是非常简单的事情。我使用socat发送的字符串(服务器正在接收并成功处理)在其末尾有一个换行符。我通过python套接字发送的字符串没有新行。在python脚本的末尾添加一个新行后,服务器会按预期接收字符串。

我只是意识到在运行python服务器脚本并在另一个端口上侦听并使用这两种方法发送字符串之后,有一个新行而不是另一个。

答案 1 :(得分:0)

根据the socat man page

  

当一个通道达到EOF时,另一个通道的写入部分将关闭。然后,socat在终止前等待timeout秒。默认值为0.5秒。

也许您需要将结束时间推迟0.5秒,如下所示:

finally:
    #sock.close()
    sock.shutdown(socket.SHUT_WR)
    time.sleep(0.5)
    sock.close()

或许,您可能需要吸收服务器的关闭消息,如下所示:

finally:
    #sock.close()
    sock.shutdown(socket.SHUT_WR)
    sock.recv(999999)
    sock.close()

答案 2 :(得分:0)

写入套接字后,您不应立即关闭套接字:关闭可能会吞下未发送的数据。

正确的工作流程是所谓的graceful shutdown

  • 想要关闭连接的部分使用套接字上的shutdown-write并继续阅读
  • 另一部分检测从套接字读取的0字节,该字节被视为文件的结尾。它关闭了它的插座
  • 启动器检测到0字节读取并可以安全地关闭套接字

所以finally部分变为:

finally:
  try:
    sock.shutdown(socket.SHUT_WR)
    while True:
        dummy = sock.recv(1024)
        if len(dummy) == 0: break
  finally:
    sock.close()