我正在编写一个将使用此方法的文件传输协议(protocol):
- 客户端以 1024 字节为单位发送二进制文件
- 服务器将接收这些 block 并将它们连接到一个对象中
- 当对象大小达到 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
最佳答案
根据socket module documentation , connection.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
。也许您的意思是无
?Python 有一个
foo = foo + bar
的快捷方式:foo += bar
。如果可用的话,使用这样的快捷方式真是太好了。请注意我如何重新安排缓冲区大小的计算。由于我现在保留两个正在运行的计数器,因此我不必在收到每个数据包后检查整个缓冲区的大小。算术运算和整数比较总是比计算列表长度更快,因此请尝试将代码安排得更像这样,以消除不必要的计算。
关于python - 在Python中连接来自connection.recv()的数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28246456/