Python Twisted通过网络发送大文件

时间:2017-09-14 11:35:22

标签: python-2.7 networking twisted

我正在尝试使用带有LineReceiver协议的Twisted通过网络发送文件。我看到的问题是,当我读取二进制文件并尝试发送块时,他们根本就不发送。

我正在使用以下方式阅读该文件:

        DateTime time = DateTime.Now;
        Console.WriteLine(time.ToString("MM/dd/yy"));

我有什么问题吗?文件被发送,当写入是多部分或者有多个文件时,它就会被发送。

如果发生单次写入,则m 注意:我已经用一段粗略的示例代码更新了问题,希望它有意义。

1 个答案:

答案 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管理大量数据的更好方法。