【问题标题】:Concatenating packets from connection.recv() in Python在 Python 中连接来自 connection.recv() 的数据包
【发布时间】:2015-01-30 23:44:02
【问题描述】:

我正在编写一个将使用此方法的文件传输协议:

  • 客户端以 1024 字节的块发送二进制文件
  • 服务器将接收这些块并将它们连接到一个对象中
  • 当对象大小变为 100 MB 或更大时,它将被写入磁盘(在新线程中)。

我猜这样做会减少磁盘写入开销,最终会减少发送时间。

我需要一种方法来连接connection.recv() 收到的数据包并将它们放入内存中。

我的部分服务器代码:

while downloadCounter<fileSize:
    filedata=client.connection.recv(chunckSize)
    downloadCounter=len(filedata)+downloadCounter
    dataBuffer.append(bfiledata)
    # save when data is 100 mb size 100000000 in binary..
    if(len(dataBuffer)>=100000000):
        tFILE=Thread(target=saveToDisk,)
        tFILE._args=(dataBuffer,file,)
        tFILE.start()
        dataBuffer=NULL

【问题讨论】:

  • 目前以何种方式无法按预期运行?

标签: python arrays file byte


【解决方案1】:

根据socket module documentationconnection.recv()返回一个字符串。我建议将这些字符串添加到列表中,然后写出该列表变得非常简单:

data_list = []
buffer_size = 0
total_size = 0

# assuming file_size, chunk_size and out_file are already defined

while total_size < file_size:

    file_data = client.connection.recv(chunk_size)

    data_list.append(file_data)

    data_length = len(file_data)
    total_size += data_length
    buffer_size += data_length

    if buffer_size >= 100000000:
        t_file = Thread(target=save_to_disk, args=(data_list, out_file))
        t_file.start()
        data_list = []
        buffer_size = 0

# Since you said your example code is just a part of your whole script, I'm
# assuming you have proper thread cleanup here. Also, don't forget to lock
# your file access since you could have multiple threads trying to write to
# it at the same time

# In your save_to_disk function, use this:
file.writelines(data_list)

我对您的代码有几点说明:

  • 您应该阅读Python Style Guide。每种语言都有或多或少的标准风格,在 Python 中,下划线优于驼峰式,并且条件子句不应该有括号。此外,运算符及其操作数之间以及等号周围应有空格。

  • 正如我在此处的示例中所做的那样,您可以创建一个 Thread 并一起提供它的参数。如果您发现自己手动访问具有前导下划线的属性,那么您可能做错了什么。按照 Python 约定,前导下划线表示该方法或属性可以随时更改,恕不另行通知,并在将来的版本中破坏您的代码。它们不是 API 的一部分,您不应依赖它们。

  • Python 中没有NULL。也许你的意思是None

  • Python 有一个foo = foo + bar 的快捷方式:foo += bar。在可用时使用此类快捷方式非常好。

  • 请注意我如何重新安排缓冲区大小的计算。由于我现在保持两个运行计数器,因此我不必在收到每个数据包后检查整个缓冲区的大小。算术运算和整数比较总是比计算列表长度要快,所以尽量把你的代码安排成这样,以消除不必要的计算。

【讨论】:

  • 请问你觉得上面的方法真的能加快文件传输速度吗?
  • 我认为您不会从这样做中看到任何速度优势。我最近尝试了类似的东西,并没有看到任何好处。根据the docs,默认情况下,Python 中的文件写入已经被缓冲,而您只是在实现另一个缓冲区。此外,它显然不能比您的客户端发送数据更快。您应该首先对其进行分析,然后花时间优化分析所揭示的瓶颈。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-15
  • 1970-01-01
  • 1970-01-01
  • 2015-12-04
相关资源
最近更新 更多