Adil.R Adil.R - 1 month ago 17
Python Question

Downloading a file using TCP(Client/Server)?

I am trying to make a TCP (Client and Server) in python to download a file that is available on the Server. I am a total beginner in networking in Python, and following a tutorial for this purpose. The problem I am getting is that whenever I try to download a file from the server I get this error:

Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner
self.run()
File "/usr/lib/python3.4/threading.py", line 868, in run
self._target(*self._args, **self._kwargs)
File "fileServer.py", line 8, in RetrFile
sock.send("EXISTS " + str(os.path.getsize(filename)));
TypeError: 'str' does not support the buffer interface


FileServer.py

import socket;
import threading;
import os;

def RetrFile(name,sock):
filename = sock.recv(1024).decode();
if os.path.isfile(filename):
sock.send("EXISTS " + str(os.path.getsize(filename)));
userResponse = sock.recv(1024).decode();
if (userResponse[:2] == 'OK'):
with open(filename,'rb') as f:
bytesToSend = f.read(1024);
sock.send(bytesToSend);
while (bytesToSend != ""):
byteToSend = f.read(1024);
sock.send(bytesToSend);
else:
sock.send("ERR");
sock.close();

def Main():
host = "127.0.0.1";
port = 5003;

s = socket.socket();
s.bind((host,port));

s.listen(5);

print("Server Started.")

while True:
c , addr = s.accept();
print("Client connected ip : " + str(addr));
t = threading.Thread(target = RetrFile,args=("retrThread",c))
t.start();
s.close();

if __name__ == '__main__':
Main();


FileClient.py

import socket

def Main():
host = "127.0.0.1";
port = 5003;

s = socket.socket();
s.connect((host,port));

filename = input("Filename? -> ");
if (filename != "q"):
s.send(filename.encode())
data = s.recv(1024)
if (data[:6] == "EXISTS"):
filesize = long(data[6:])
message = input("File Exists, " + str(fielsize) + "Bytes, download? (Y/N)? -> ");
if (message == "Y"):
s.send("OK")
f = open('new_'+filename,'wb')
data = s.recv(1024)
totalRecv = len(data)
f.write(data)
while(totalRecv < filesize):
data = s.recv(1024);
totalRecv += len(data)
f.write(data)
print("{0:.2f}".format((totalRecv/float(filesize))*100 + "%Done"));
print("Download Complete!");

else:
print("File does not exist!");
s.close();

if __name__ == '__main__':
Main();

Answer

You need to be sending bytes to the socket, not a string. You can convert a string to a bytes with .encode() Try:

message = "EXISTS " + str(os.path.getsize(filename)))
sock.send(message.encode())

As a side note, you don't need semicolons when using Python, so I would recommend removing them from your code.