【问题标题】:Simple Python Server Client File Transfer简单的 Python 服务器客户端文件传输
【发布时间】:2018-03-16 03:06:02
【问题描述】:

我正在进行这个简单的 python 服务器-客户端文件传输项目。 每边有两个部分。首先,客户端将文件发送到服务器的第一部分。然后服务器附加一行并将文件在第二部分发送回客户端。

我的问题是,由于某种原因,只要我有返回文件代码,服务器代码就会卡在接收状态。如果我应该注释掉代码的第二部分,服务器会收到客户端发送的所有文件。否则它会在接收时冻结。是的,客户确实发送了它。

你可以忽略所有的打印命令,只是在那里看看问题出在哪里。

服务器代码:

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

【问题讨论】:

  • 打印输出是什么?
  • 客户端会说它发送数据,但服务器似乎没有收到任何东西。

标签: python sockets networking


【解决方案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

希望能帮到你!

【讨论】:

    【解决方案2】:

    我解决这个问题的方法是先发送文件大小,然后服务器可以在收到整个文件后立即停止等待。我不知道是否有更好的解决方案,但这就像一个魅力:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 2014-10-06
      • 1970-01-01
      • 1970-01-01
      • 2016-12-27
      相关资源
      最近更新 更多