希望在 Python 中模拟 socat 的功能
Posted
技术标签:
【中文标题】希望在 Python 中模拟 socat 的功能【英文标题】:Looking to emulate the functionality of socat in Python 【发布时间】:2017-02-12 18:57:42 【问题描述】:我需要使用 python 将字符串发送到本地主机上的特定端口。
我可以通过在命令行上使用 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 接受器来侦听特定地址和端口上的 tcp 连接。
【问题讨论】:
您的代码非常适合我。我的服务器nc -l 55559
在其标准输出上显示 json 字符串。请描述您正在使用的服务器,以及是什么让您认为“对接收 socat 数据的进程没有任何影响”。
@Robᵩ 我尝试向其发送字符串的服务器是 C++ 程序的一部分,该程序使用 boost asio 接受器侦听特定地址和端口上的 tcp 连接。
【参考方案1】:
原来是一件非常简单的事情。我使用 socat 发送的字符串(服务器正在成功接收和处理)在它的末尾有一个换行符。我通过 python 套接字发送的字符串没有新行。在 python 脚本的末尾添加新行后,服务器按预期接收字符串。
在运行 python 服务器脚本侦听不同端口并使用这两种方法发送字符串后,我才意识到一个后有一个换行符,而不是另一个后一个换行符。
【讨论】:
【参考方案2】:你永远不能在写入套接字后立即关闭套接字:关闭可能会吞下仍未发送的数据。
正确的工作流程是所谓的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()
【讨论】:
感谢您的建议,但进行这些更改并没有改变结果,服务器似乎仍然没有收到任何消息。【参考方案3】:根据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()
【讨论】:
对结果没有任何影响。还是谢谢。以上是关于希望在 Python 中模拟 socat 的功能的主要内容,如果未能解决你的问题,请参考以下文章