【发布时间】:2015-06-30 23:34:25
【问题描述】:
我已经设置了一个非常简单的 Python 代理服务器。它的目的是获取一个 TCP 流(视频)并将该 TCP 流转发给多个客户端(目前只是测试一个开始)。一切正常,直到我尝试转发 (o.send(data)) 数据,然后它将接收/发送几个数据包,冻结,然后大约一两分钟后接收/发送几个更多数据包并再次冻结。
如果我只是简单地将传入的数据加载到一个变量中,它根本不会减慢速度。如果我都将传入的数据加载到数据变量中,但将随机数据块发送到客户端而不是接收到的数据,它也不会冻结。我觉得可能存在竞争条件或类似情况,但 .recv() 不应该阻塞,所以我不知道死锁来自哪里。一旦recv填充了数据,它应该能够发送它吧?然后无限期地冲洗/重复。我可以使用 top -bn1 检查 CPU 利用率,python 脚本似乎根本没有使用任何 cpu。
死锁发生在 .recv() 和 .send() 之间。
如果我输入调试打印,它将打印“收到数据!” ......暂停......“数据发送!” “数据收到!”....
import socket
# Listen for gstreamer TCP stream.
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("192.168.1.1", 911))
s.listen(5)
# Connect to the video player
o = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
o.connect(("192.168.2.2",910))
clientsocket, address = s.accept()
while 1:
# Receive the video data.
data = clientsocket.recv(4096)
# Forward it to the video player
o.send(data)
print 'o'
谢谢!
【问题讨论】:
-
客户端是什么样子的?
-
我已经用一个播放视频流的 .NET windows 应用程序和一个看起来就像这个代理服务器减去“o”套接字的虚拟 Python 客户端进行了尝试。无论哪种方式,性能都是相同的。 .NET windows 应用程序在没有中间人的情况下运行,所以我知道它很乐意在没有中间人的情况下以足够的速率接收这些数据。
-
实际上看起来可能只是读取数据有问题。我调整了中继服务器代码,只将每个数据包添加到一个数组中,它以完全相同的方式死锁。例如data.append(clientsocket.recv(4096))
-
我不确定 StackOverflow 的正确礼仪是什么,但我发现了我认为的问题。它最终成为一个不好的 NIC。
-
自己写答案,然后接受。