我正在进行这个简单的python服务器 - 客户端文件传输项目。 每边有两个部分。首先,客户端将文件发送到服务器以获取第一部分。然后,服务器附加一行,并在第二部分将文件发送回客户端。
我的问题是,由于某种原因,只要我有返回文件代码,服务器代码就会停止接收。如果我要注释掉代码的第二部分,服务器将接收客户端发送的所有文件。否则它会在收到时冻结。是的,客户确实发送了它。
您可以忽略所有打印命令,只是为了查看问题所在。
servercode:
import socket
ssFT = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssFT.bind((socket.gethostname(), 8756))
ssFT.listen(1)
while True:
(conn, address) = ssFT.accept()
text_file = 'fileProj.txt'
#Receive, output and save file
with open(text_file, "wb") as fw:
print("Receiving..")
while True:
print('receiving')
data = conn.recv(1024)
print('Received: ', data.decode('utf-8'))
if not data:
print('Breaking from file write')
break
fw.write(data)
print('Wrote to file', data.decode('utf-8'))
fw.close()
print("Received..")
#Append and send file
print('Opening file ', text_file)
with open(text_file, 'ab+') as fa:
print('Opened file')
print("Appending string to file.")
string = b"Append this to file."
fa.write(string)
fa.seek(0, 0)
print("Sending file.")
while True:
data = fa.read(1024)
conn.send(data)
if not data:
break
fa.close()
print("Sent file.")
break
ssFT.close()
客户代码:
import socket
csFT = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
csFT.connect((socket.gethostname(), 8756))
text_file = 'passphrase.txt'
#Send file
with open(text_file, 'rb') as fs:
#Using with, no file close is necessary,
#with automatically handles file close
while True:
data = fs.read(1024)
print('Sending data', data.decode('utf-8'))
csFT.send(data)
print('Sent data', data.decode('utf-8'))
if not data:
print('Breaking from sending data')
break
fs.close()
#Receive file
print("Receiving..")
with open(text_file, 'wb') as fw:
while True:
data = csFT.recv(1024)
if not data:
break
fw.write(data)
fw.close()
print("Received..")
csFT.close()
答案 0 :(得分:1)
我使用Python 3在本地测试了您的代码。
我看到的问题是服务器代码中的 conn.recv 。由于 conn.recv 阻止连接,它正在等待更多数据。
我找到的解决方案是向服务器发送命令,通知BEGIN和END数据传输,如下所示:
#Send file
with open(text_file, 'rb') as fs:
#Using with, no file close is necessary,
#with automatically handles file close
csFT.send(b'BEGIN')
while True:
data = fs.read(1024)
print('Sending data', data.decode('utf-8'))
csFT.send(data)
print('Sent data', data.decode('utf-8'))
if not data:
print('Breaking from sending data')
break
csFT.send(b'ENDED') # I used the same size of the BEGIN token
fs.close()
with open(text_file, "wb") as fw:
print("Receiving..")
while True:
print('receiving')
data = conn.recv(32)
if data == b'BEGIN':
continue
elif data == b'ENDED':
print('Breaking from file write')
break
else:
print('Received: ', data.decode('utf-8'))
fw.write(data)
print('Wrote to file', data.decode('utf-8'))
fw.close()
print("Received..")
Client.py完整代码: https://pastebin.com/LySsgEe4
Server.py完整代码: https://pastebin.com/KADZpqkM
我希望能帮到你!
答案 1 :(得分:0)
我解决同样问题的方法是首先发送文件大小,然后服务器可以在收到整个文件后立即停止等待。我不知道是否有更好的解决方案,但这就像一个魅力:
BUFFER_SIZE = 1024
<强> client.py 强>
import os
fsize = os.path.getsize(text_file)
csFT.send(str(fsize).encode('utf-8'))
with open(text_file, 'rb') as fs:
data = fs.read(BUFFER_SIZE)
while data:
csFT.send(data)
data = fs.read(BUFFER_SIZE)
<强> server.py 强>
with open(text_file, 'wb') as fw:
msg = ssFT.recv(BUFFER_SIZE)
fsize = int(msg.decode('utf-8'))
rsize = 0
while True:
data = ssFT.recv(BUFFER_SIZE)
rsize = rsize + len(data)
fw.write(data)
if rsize >= fsize:
print('Breaking from file write')
break