【问题标题】:Sending files to client from server via socket/ftp python通过socket/ftp python从服务器向客户端发送文件
【发布时间】:2020-04-17 21:18:18
【问题描述】:

我是 python 新手。使用 Ubuntu 18.04、python 3.6。

尝试编写脚本以将任何文件从服务器发送到客户端(当前正在尝试发送 .pdf 文件),反之亦然。

之前我使用套接字发送文件,但遇到了扩展问题(例如发送 .pdf 文件但收到 .txt 文件 - 无法弄清楚为什么会发生这种情况)。然后使用了ftp,但现在卡在了某个地方。

服务器脚本:

import socket
import os

s = socket.socket()
host = ""
port = 9999

s.bind((host, port))
s.listen(5)
print("Binding Done\n")

socket_object, address = s.accept()
print("Connection Established\n")

print("Sending file...")
f = open("cds.pdf", 'rb')
while f.read(1024):
    socket_object.send(f.read(1024))

print("Files Send")
f.close()
socket_object.close()
s.close()

客户端脚本:

import socket
import os
from ftplib import FTP

ftp = FTP()
s = socket.socket()
host = "192.168.43.16"
port = 9999

s.connect((host, port))
#ftp.connect(host = "192.168.43.16", port = 9999)

print("Receiving data...")

f = open("cds_copy.pdf", 'wb')
while True:
    ftp.retrbinary('RETR cds_copy.pdf', f.write, 1024)

ftp.storbinary('STOR cds_copy.pdf', open('cds_copy.pdf', 'rb'))
print("File Collected")
ftp.quit()
f.close()
s.close()

错误:

$python3 client.py
Receiving data...
Traceback (most recent call last):
  File "client.py", line 17, in <module>
    ftp.retrbinary('RETR cds_copy.pdf', f.write, 1024)
  File "/usr/lib/python3.6/ftplib.py", line 441, in retrbinary
    self.voidcmd('TYPE I')
  File "/usr/lib/python3.6/ftplib.py", line 277, in voidcmd
    self.putcmd(cmd)
  File "/usr/lib/python3.6/ftplib.py", line 199, in putcmd
    self.putline(line)
  File "/usr/lib/python3.6/ftplib.py", line 194, in putline
    self.sock.sendall(line.encode(self.encoding))
AttributeError: 'NoneType' object has no attribute 'sendall'

无法找出错误。

任何建议都会有所帮助。谢谢你。

【问题讨论】:

    标签: python sockets ftp ftplib


    【解决方案1】:

    FTP 是RFC 959 中定义的应用程序协议。如果你想在你的客户端中使用它,你必须有一个说 FTP 协议的服务器。您的服务器不使用 FTP 协议,而只是将文件的内容转储到客户端。在这种情况下,客户端应该完全期望这一点,而不是说 FTP,即

    import socket 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(("192.168.43.16", 9999))
    f = open("out.pdf","wb")
    while True:
        buf = s.recv(1024)
        if buf == "":
            break
        f.write(buf)
    

    除了你的服务器坏了:它首先从文件中读取 1024 字节,丢弃它,然后读取下一个 1024 字节并将其发送给客户端:

    while f.read(1024):                           # read 1024 byte from f but discard
        socket_object.send(f.read(1024))          # read another 1024 byte from f and send
    

    这可能不是您想要的。相反,它应该看起来更像这样:

    while True:
        buf = f.read(1024)              # read bytes from f
        if buf == "":                   # check that not done
            break
        socket_object.sendall(buf)     # write previously read bytes to client
    

    请注意,这也使用sendall 而不是send,因为只有sendall 会注意实际发送所有给定的数据。一个简单的send 可能只发送部分数据,您必须检查返回值以了解发送了多少。

    【讨论】:

    • 谢谢。这行得通。早些时候我尝试了几乎相同的事情,但我猜问题出在缓冲区(用于损坏的文件)。
    猜你喜欢
    • 2023-04-03
    • 2011-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多