我正在尝试使用带有LineReceiver协议的Twisted通过网络发送文件。我看到的问题是,当我读取二进制文件并尝试发送块时,他们根本就不发送。
我正在使用以下方式阅读该文件:
DateTime time = DateTime.Now;
Console.WriteLine(time.ToString("MM/dd/yy"));
我有什么问题吗?文件被发送,当写入是多部分或者有多个文件时,它就会被发送。
如果发生单次写入,则m 注意:我已经用一段粗略的示例代码更新了问题,希望它有意义。
答案 0 :(得分:1)
_BuildMessage
返回两个元组:(msgs, '')
。
您的网络代码对此进行了迭代:
msgs = self._BuildMessage(MsgID.ExportFileToMaster, params)
for m in msgs:
因此,您的网络代码首先尝试发送json编码数据列表,然后尝试发送空字符串。它很可能会引发异常,因为您无法使用sendLine
发送任何内容列表。如果您没有看到异常,则忘记启用日志记录。您应始终启用日志记录,以便可以查看发生的任何异常。
此外,您正在使用time.sleep
,而您不应该在基于Twisted的程序中执行此操作。如果你这样做试图避免接收器过载,你应该使用TCP的本机背压,而不是注册一个可以接收暂停和恢复通知的生产者。无论如何,time.sleep
(以及对所有数据的循环)将阻塞整个反应器线程并阻止进行任何进展。结果是大多数数据在发送之前将在本地进行缓冲。
此外,您的代码从非反应器线程调用LineReceiver.sendLine
。这有不确定的结果,但你可能指望它不起作用。
此循环在主线程中运行:
while 1:
time.sleep(0.01)
if connectionToServer == None: continue
if trySend == True:
protocol.ProccessTransmitJobToNode(None, None)
trySend = False
当反应堆在另一个线程中运行时:
netThread = threading.Thread(target=reactor.run, kwargs={"installSignalHandlers": False})
netThread.start()
ProcessTransmitJobToNode
只需拨打self.sendLine
:
def ProccessTransmitJobToNode(self, msg, connection):
rootDir = '../documentation/configs/Wooster'
exportedFiles = ['consoleLog.txt', 'blob.dat']
params = {
'Status' : 'buildStatus',
'TaskID' : 'taskID',
'Name' : 'taskName',
'Exports' : len(exportedFiles),
}
msg, statusStr = self._BuildMessage(101, params)
connection.sendLine(msg[0])
您应该完全从应用程序中删除线程的使用。使用reactor.callLater
可以更好地管理基于时间的事件(您的主线程循环有效地生成对ProcessTransmitJobToNode
的调用,每秒一百次(trySend
标志的模数效果))。
您可能还想查看https://github.com/twisted/tubes作为使用Twisted管理大量数据的更好方法。