I am new to python. Using Ubuntu 18.04, python 3.6.
Tried writing a script to send ANY File from server to client (currently trying to send .pdf file) and vice versa.
Earlier i used sockets to send file, but was facing problems with extensions (like sending .pdf file but received .txt file - could not figure out why this was happening). Then used ftp, but stuck at one point right now.
SERVER SCRIPT:
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()
CLIENT SCRIPT:
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()
ERROR:
$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'
Unable to figure out the error.
Any suggestions will be helpful. Thanking You.
FTP is an application protocol as defined in RFC 959 . If you want to use it in your client you must have a server speaking that FTP protocol. Your server does not speak the FTP protocol but simply dumps the content of a file to the client. In this case the client should expect exactly this and not speak FTP, ie
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)
Apart from that your server is broken: it first reads 1024 bytes from the file, discards it and then reads the next 1024 byte and sends it to the client:
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
This is likely not what you've intended. Instead it should look more like this:
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
Note that this also uses sendall
instead of send
since only sendall
will take care to actually send all given data. A simple send
instead might only send part of the data and you have to check the return value to find out how much was send.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.