连接来自的数据包连接.recv()在Python中

2024-06-01 07:02:49 发布

您现在位置:Python中文网/ 问答频道 /正文

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

  • 客户端发送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

Tags: 对象方法服务器协议客户端len字节二进制
1条回答
网友
1楼 · 发布于 2024-06-01 07:02:49

根据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中,下划线比camelcase更受欢迎,条件子句不应该在其周围加括号。此外,运算符与其操作数之间以及等号赋值之间应该有空格。

  • 正如我在这里的例子中所做的,您可以创建一个Thread并一起提供它的参数。如果您发现自己手动访问一个带有前导下划线的属性,则可能是您做错了什么。根据Python惯例,前导下划线表示可以随时更改该方法或属性,而不会发出任何通知,并在将来的版本中破坏代码。它们不是API的一部分,您不应该依赖它们。

  • Python中没有NULL。也许你是说None

  • Python有一个foo = foo + bar:foo += bar的快捷方式。如果可以的话,最好使用这样的快捷方式。

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

相关问题 更多 >