3

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.

1 Answer 1

2

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, i.e.

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. This worked. Earlier i tried almost the same thing but i guess the problem was of buffer (file used to get corrupt).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.