简单的Python Server客户端文件传输

时间:2017-10-16 16:53:47

标签: python sockets networking

我正在进行这个简单的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()

2 个答案:

答案 0 :(得分:1)

我使用Python 3在本地测试了您的代码。

我看到的问题是服务器代码中的 conn.recv 。由于 conn.recv 阻止连接,它正在等待更多数据。

我找到的解决方案是向服务器发送命令,通知BEGIN和END数据传输,如下所示:

client.py

#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()

server.py

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