gpt4 book ai didi

python - 使用 Python 通过 TCP 传输文件

转载 作者:可可西里 更新时间:2023-11-01 02:33:43 37 4
gpt4 key购买 nike

我目前正在开发一个 python 项目,该项目需要通过 Python 套接字将文件从客户端传输到服务器。这是我当前的代码,但它不会传输整个文件,但根据文件大小,总会有一些缺失或额外的字节。

_con 和 con 是通过 python 套接字连接的连接包装器。

客户:

def _sendFile(self, path):
sendfile = open(path, 'rb')
data = sendfile.read()

self._con.sendall(data)

self._con.send(bytes('FIN', 'utf8'))
# Get Acknowledgement
self._con.recv(6)

def _recieveFile(self, path):
# Recieve the file from the client
writefile = open(path, 'wb')
i = 0
while (1):
rec = self.con.recv(1024)
if (rec.endswith(b'FIN')):
break
writefile.write(rec)

self.con.send(b'ACK')

最佳答案

虽然您遇到的第一个问题是没有将收到的最后一 block 数据写入输出文件,但您还有其他一些问题。

可以通过将 if 语句更改为如下内容来解决您当前的问题:

if (rec.endswith(b'FIN')):
writefile.write(rec[:-3]) # Ignore the last 3 bytes
break

你还有其他问题:

  1. 如果文件包含字符 FIN,则字符将是读取缓冲区中的最后 3 个字符的概率约为 1024 分之一,您的代码将错误地读取该字符作为结束标记,并提前终止。

  2. 还有 1024 分之 2 的机会 FIN 标记将拆分为对 read() 的两次调用,使用 recFFI 结尾。

这两个问题都是因为 TCP 是基于流的协议(protocol),在用户层没有数据包的概念。

一个明显的解决方法是在传输文件之前使用固定大小的长度指示,接收方读取它,然后读取正确的字节数。

像这样:

def _sendFile(self, path):
sendfile = open(path, 'rb')
data = sendfile.read()

self._con.sendall(encode_length(len(data)) # Send the length as a fixed size message
self._con.sendall(data)


# Get Acknowledgement
self._con.recv(1) # Just 1 byte


def _recieveFile(self, path):
LENGTH_SIZE = 4 # length is a 4 byte int.
# Recieve the file from the client
writefile = open(path, 'wb')
length = decode_length(self.con.read(LENGTH_SIZE) # Read a fixed length integer, 2 or 4 bytes
while (length):
rec = self.con.recv(min(1024, length))
writefile.write(rec)
length -= sizeof(rec)

self.con.send(b'A') # single character A to prevent issues with buffering

当然,在发送/接收长度时,需要注意长度字段中字节的顺序。

关于python - 使用 Python 通过 TCP 传输文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5020658/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com