Simple Server file program, file always doesn't exist - python

i recently tried a tutorial on how to create a simple file server program with python. i don't know why everytime i check whether the file exists or not, it always tells me the file doesn't exist, here is the code
# server.py
import socket
import threading
import os
def RetFile(FileName, sock):
FileName = sock.recv(1024)
exists = os.path.isfile(FileName)
if exists:
sock.send(str.encode("EXISTS " + str(os.path.getsize(FileName))))
UserResponce = sock.recv(1024)
if UserResponce[:2] == "OK":
with open(FileName, 'rb') as f:
bytesToSend = f.read(1024)
sock.send(bytesToSend)
while bytesToSend != "":
bytesToSend = f.read(1024)
sock.send(bytesToSend)
else:
sock.send(str.encode("ERR"))
sock.close()
def Main():
host = '127.0.0.1'
port = 5001
s = socket.socket()
s.bind((host, port))
s.listen(5)
print('Server Started')
while True:
conn, addr = s.accept()
print('Client Connected -> ', str(addr))
t = threading.Thread(target=RetFile, args=("retrThread", conn))
t.start()
if __name__ == '__main__':
Main()
# client.py
import socket
def Main():
host = '127.0.0.1'
port = 5001
s = socket.socket()
s.connect((host, port))
filename = input('File Name -> ')
if filename != 'q':
s.send(str.encode(filename))
data = s.recv(1024)
if data[:6] == "EXISTS ":
filesize = float(data[6:])
message = input('File Exists: ' + str(filesize) + ' Bytes, Download? (Y/N) -> ')
if message == 'Y':
s.send(str.encode("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 Doesn't Exist")
s.close()
if __name__ == '__main__':
Main()
so where is the error of the code? the tutorial uses python 2.x and i use 3.x so i have some minor changes, and i'm new to this language so any help would be appreciated, thank you!

There were some issues in you code mostly related to byte conversion . you cannot send string on socket interface if you are using python 3 or above, with python 2 it works fine. So every message has to be changed to bytes before sending on socket i have fixed all such issues . Download is working fine
Fixed Server
# server.py
import socket
import threading
import os
def RetrFile(name, sock):
filename = sock.recv(1024)
if os.path.isfile(filename):
sock.send(b"Exist " + str(os.path.getsize(filename)).encode())
userResponse = sock.recv(1024)
if userResponse.decode() == 'OK':
with open(filename, 'rb') as f:
bytesToSend = f.read(1024)
while bytesToSend.decode() != "":
sock.send(bytesToSend)
bytesToSend = f.read(1024)
else:
sock.send(b"ERR")
sock.close()
def Main():
host = '127.0.0.1'
port = 5000
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()
if __name__ == '__main__':
Main()
Fixed Client
# client.py
import socket
def Main():
host = '127.0.0.1'
port = 5000
s = socket.socket()
s.connect((host, port))
filename = bytearray(input("filename.. ").encode())
if filename != 'q':
s.send(filename)
data = s.recv(1024)
if data[:6].decode().rstrip().upper() == 'EXIST':
filesize = data[6:].decode().rstrip()
message = input("File exists, " + filesize+ "Bytes, download..? (Y/N)")
if message.upper() == 'Y':
totalRecv = 0
s.send(b'OK')
f = open('new_' + filename.decode(), 'wb')
data = s.recv(1024)
while data.decode() != "":
totalRecv += len(data)
data = s.recv(1024)
f.write(data)
print("{:2f}".format((totalRecv/float(filesize))*100)+ "Done")
print("Download complete")
else:
print("File doesn't exist")
if __name__ == '__main__':
Main()

Apart from the fact that a file may not exist, there is one obvious problem:
if data[:6] == "EXISTS ":
can never be True because data[:6] is a string of 6 characters, and "EXISTS " is 7 characters long.

Related

Type Error using Socket communication even while decoding to byte string

Hello I got a problem with a type error I cant get rid off.
I have build a server named processA.py and a client processB.py
I start the server calling processA and it starts up
I start the client calling processB and it starts up
Now I input the name of the file I want to send over a socket.
The image must be in the same folder as the programms.
You can use the sample code from below for reproducing the error.
I choose: lena.jpg
I get an error in line 15, in of my processA.py:
sock.send("EXISTS" + str(os.path.getsize(filenameByte))) TypeError: a
bytes-like object is required, not 'str'
processA.py
'''
Created on 29 Nov 2017
#author: Poor Student
'''
import numpy
import socket
import threading
import os
def RtrFile(name, sock):
filenameByte = sock.recv(1024)
filenameStr = filenameByte.decode('ascii')
if os.path.isfile(filenameStr):
sock.send("EXISTS" + str(os.path.getsize(filenameByte)))
userResponse = sock.recv(1024)
if userResponse[:2] == 'OK':
with open(filenameByte, 'rb') as f:
bytesToSend = f.read(1024)
sock.send(bytesToSend)
while bytesToSend != "":
bytesToSend = f.read(1024)
sock.send(bytesToSend)
else:
sock.send("ERR")
sock.close()
def Main():
host = "127.0.0.1"
port = 5000
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 = RtrFile, args=("rtrThread",c))
t.start()
s.close()
if __name__ == "__main__":
Main()
processB.py
'''
Created on 29 Nov 2017
#author: Poor Student
'''
import socket
def Main():
host = "127.0.0.1"
port = 5000
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 = int(data[6:])
message = input("File Exists, " +str(filesize) + "Bytes, download? (Y/N)? ->")
if message == "Y" or 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:.f)".format((totalRecv)/float(filesize))*100 +"done")
print("Download Complete")
else:
print("File does not exists")#
s.close()
if __name__ == "__main__":
Main()
I found an answer. In python 3 you have allways convert your Strings to byte strings when sending them. After sending them to the receiver you have to decode them again and this must be done for the hole communication which is why the error allways shows up in the same module.
Process A:
'''
Created on 29 Nov 2017
#author: Happy student
'''
import numpy
import socket
import threading
import os
from idlelib.IOBinding import encoding
def RtrFile(name, sock):
filenameByte = sock.recv(1024)
filenameStr = filenameByte.decode('ascii')
print("FilenameStr",filenameStr)
if os.path.isfile(filenameStr):
print("Type:",type(filenameByte))
print(os.path.getsize(filenameByte))#
sendStr = "EXISTS" + str(os.path.getsize(filenameByte))
#Convert the string to byte because otherwise it will not be send
sock.send((sendStr.encode(encoding)))
userResponse = sock.recv(1024)
#the Responce will be received in byte and will be converted to a string to make it checkable
userResponceStr = userResponse.decode('ascii')
if userResponceStr[:2] == 'OK':
with open(filenameByte, 'rb') as f:
bytesToSend = f.read(1024)
sock.send(bytesToSend)
while bytesToSend != "":
bytesToSend = f.read(1024)
sock.send(bytesToSend)
else:
print("User response not known")
else:
sendStr = "ERR"
sock.send(sendStr.encode(encoding))
sock.close()
def Main():
host = "127.0.0.1"
port = 5000
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 = RtrFile, args=("rtrThread",c))
t.start()
s.close()
if __name__ == "__main__":
Main()
processB.py
'''
Created on 29 Nov 2017
#author: Happy student
'''
import socket
from idlelib.IOBinding import encoding
def Main():
host = "127.0.0.1"
port = 5000
s = socket.socket()
s.connect((host,port))
filename = input("Filename? -> ")
if filename != "q":
s.send(filename.encode())
data = s.recv(1024)
dataStr = data.decode('ascii')
if dataStr[:6] == "EXISTS":
filesize = int(dataStr[6:])
message = input("File Exists, " +str(filesize) + "Bytes, download? (Y/N)? ->")
if message == "Y" or message =="y":
sendStr = "OK"
s.send(sendStr.encode(encoding))
#create new file new_filename and
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("Download Complete")
else:
print(message +"was not noticed")
exit()
else:
print("File does not exists")#
s.close()
if __name__ == "__main__":
Main()

Python File Server, login function not working

I made a python file server a while back and just recently came back to it. It is a very simple program but i wanted to add some more features to it, one of those being to add some security. For this reason i made a hashed login password and put that in a .txt file stored on the server computer. The way the program is supposed to work is every time the client connects to the server they must enter a password. Then the raw_entry is sent through a socket and checked on the server side if it is correct, if is is not then the user has two more tries to enter the password. For some reason this is not working.
The server:
from passlib.hash import pbkdf2_sha256
import socket
import threading
import os
def login():
loop = 1
while loop <= 3:
passwd = sock.recv(1024)
with open('passtor.txt', 'r') as f:
hash = f.read()
if pbkdf2_sha256.verify(passwd, hash):
s.send("Access Granted")
loop = 4
else:
s.send("Verification Failure")
loop += 1
if loop == 3:
sock.close()
def RetrFile(name, sock):
filename = sock.recv(1024)
if os.path.isfile(filename):
sock.send("EXISTS " + str(os.path.getsize(filename)))
userResponse = sock.recv(1024)
if userResponse[:2] == 'OK':
with open(filename, 'rb') as f:
bytesToSend = f.read(1024)
sock.send(bytesToSend)
while bytesToSend != "":
bytesToSend = f.read(1024)
sock.send(bytesToSend)
else:
sock.send("ERR ")
sock.close()
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#s.connect(('google.com', 0))
host = s.getsockname()[0]
port = 5000
s = socket.socket()
s.bind((host,port))
s.listen(5)
print "File Server Initiated"
print("Server Address-> " + host + " <-")
while True:
c, addr = s.accept()
print "Client Connected ip-> " + str(addr) + " <-"
t1 = threading.Thread(target=login, args=("RetrThread", c))
t2 = threading.Thread(target=RetrFile, args=("RetrThread", c))
t1.start()
t2.start()
s.close()
except:
print("Program Error, \nTermination Complete")
The client:
import socket
host = '127.0.0.1'
port = 5000
s = socket.socket()
s.connect((host, port))
loop = True
while loop == True:
passwd = raw_input("Admin Password-> ")
s.send(passwd)
answer = s.recv(1024)
if answer == 'Verification Failure':
loop = True
print(answer)
elif answer == 'Access Granted':
loop = False
print(answer)
filename = raw_input("Filename? -> ")
if filename != 'q':
s.send(filename)
data = s.recv(1024)
if data[:6] == 'EXISTS':
filesize = long(data[6:])
message = raw_input("File exists, " + str(filesize) +"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!"
f.close()
else:
print "File Does Not Exist!"
s.close()
You are passing two arguments to the login function here:
t1 = threading.Thread(target=login, args=("RetrThread", c))
They are not declared in the function declaration:
def login():
Either remove the args parameter from the call to threading.Thread or add the arguments to the function declaration.

Python file server

I followed a tutorial to make this, and I'm trying to add an ls command so you can see the files to download. The code works, and all the prints return the right things, but the client only shows six letters of one of the files.
Server:
import socket
import threading
import os
def RetrFile(name, sock):
filename = sock.recv(1024)
if filename != "ls":
if os.path.isfile(filename):
sock.send("EXISTS " + str(os.path.getsize(filename)))
userResponse = sock.recv(1024)
if userResponse[:2] == 'OK':
with open(filename, 'rb') as f:
bytesToSend = f.read(1024)
sock.send(bytesToSend)
while bytesToSend != "":
bytesToSend = f.read(1024)
sock.send(bytesToSend)
else:
sock.send("ERR ")
sock.close()
else:
dir_path = os.path.dirname(os.path.realpath(__file__))
retval = os.listdir(dir_path)
print retval
for ret in retval:
print ret
sock.send(ret)
def Main():
host = '192.168.0.125'
port = 5000
s = socket.socket()
s.bind((host,port))
s.listen(5)
print "Server Started."
while True:
c, addr = s.accept()
print "client connedted ip:<" + str(addr) + ">"
t = threading.Thread(target=RetrFile, args=("RetrThread", c))
t.start()
s.close()
if __name__ == '__main__':
Main()
Directory with the Python file (files to download): directory
Server Output: "client connedted ip:<('192.168.0.112', 49546)>
['runmeee.exe', 'Untitled.png', 'putty.exe', 'pyserver.py']
runmeee.exe
Untitled.png
putty.exe
pyserver.py"
Client output: runmee

Trying to create a crude send/receive through TCP in python

So far I can send files to my "fileserver" and retrieve files from there as well. But i can't do both at the same time. I have to comment out one of the other threads for them to work. As you will see in my code.
SERVER CODE
from socket import *
import threading
import os
# Send file function
def SendFile (name, sock):
filename = sock.recv(1024)
if os.path.isfile(filename):
sock.send("EXISTS " + str(os.path.getsize(filename)))
userResponse = sock.recv(1024)
if userResponse[:2] == 'OK':
with open(filename, 'rb') as f:
bytesToSend = f.read(1024)
sock.send(bytesToSend)
while bytesToSend != "":
bytesToSend = f.read(1024)
sock.send(bytesToSend)
else:
sock.send('ERROR')
sock.close()
def RetrFile (name, sock):
filename = sock.recv(1024)
data = sock.recv(1024)
if data[:6] == 'EXISTS':
filesize = long(data[6:])
sock.send('OK')
f = open('new_' + filename, 'wb')
data = sock.recv(1024)
totalRecieved = len(data)
f.write(data)
while totalRecieved < filesize:
data = sock.recv(1024)
totalRecieved += len(data)
f.write(data)
sock.close()
myHost = ''
myPort = 7005
s = socket(AF_INET, SOCK_STREAM)
s.bind((myHost, myPort))
s.listen(5)
print("Server Started.")
while True:
connection, address = s.accept()
print("Client Connection at:", address)
# u = threading.Thread(target=RetrFile, args=("retrThread", connection))
t = threading.Thread(target=SendFile, args=("sendThread", connection))
# u.start()
t.start()
s.close()
CLIENT CODE
from socket import *
import sys
import os
servHost = ''
servPort = 7005
s = socket(AF_INET, SOCK_STREAM)
s.connect((servHost, servPort))
decision = raw_input("do you want to send or retrieve a file?(send/retrieve): ")
if decision == "retrieve" or decision == "Retrieve":
filename = raw_input("Filename of file you want to retrieve from server: ") # ask user for filename
if filename != "q":
s.send(filename)
data = s.recv(1024)
if data[:6] == 'EXISTS':
filesize = long(data[6:])
message = raw_input("File Exists, " + str(filesize)+"Bytes, download?: Y/N -> ")
if message == "Y" or message == "y":
s.send('OK')
f = open('new_' + filename, 'wb')
data = s.recv(1024)
totalRecieved = len(data)
f.write(data)
while totalRecieved < filesize:
data = s.recv(1024)
totalRecieved += len(data)
f.write(data)
print("{0: .2f}".format((totalRecieved/float(filesize))*100)) + "% Done" # print % of download progress
print("Download Done!")
else:
print("File does not exist!")
s.close()
elif decision == "send" or decision == "Send":
filename = raw_input("Filename of file you want to send to server: ")
if filename != "q":
s.send(filename)
if os.path.isfile(filename):
s.send("EXISTS " + str(os.path.getsize(filename)))
userResponse = s.recv(1024)
if userResponse[:2] == 'OK':
with open(filename, 'rb') as f:
bytesToSend = f.read(1024)
s.send(bytesToSend)
while bytesToSend != "":
bytesToSend = f.read(1024)
s.send(bytesToSend)
else:
s.send('ERROR')
s.close()
s.close()
I'm still new to programming, so this is quite tough for me. All in all i'm just trying to figure out how to send AND receive files without having to comment out the bottom threads in my SERVER CODE.
Please and thank you!
On the serverside, you're trying to use the same connection for your two threads t and u.
I think it might work if you listened for another connection in your while True: loop on the server, after you started your first thread.
I always use the more high-level socketserver module (Python Doc on socketserver), which also natively supports Threading. I recommend checking it out!
By the way, since you do a lot of if (x == 'r' or x == 'R'): you could just do if x.lower() == 'r'
just made an if statement sending a True or False and that will decide which thread to execute.

Sending contents of file to server - python socket

When doing the put command I am getting this error. I can't seem to figure out why.
line 41, in
data = client.recv(1024)
error: [Errno 10053] An established connection was aborted by the software in your host machine
Here is my client code:
import socket
import sys
import os
HOST = 'localhost'
PORT = 8082
size = 1024
def ls():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST,PORT))
s.send(userInput)
result = s.recv(size)
print result
s.close()
return
def put(command):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send(command)
string = command.split(' ', 1)
input_file = string[1]
with open(input_file, 'rb') as file_to_put:
for data in file_to_put:
s.sendall(data)
s.close()
return
def get(command):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send(command)
string = command.split(' ', 1)
input_file = string[1]
with open(input_file, 'wb') as file_to_get:
while True:
data = s.recv(1024)
print data
if not data:
break
file_to_get.write(data)
file_to_get.close()
s.close()
return
done = False
while not done:
userInput = raw_input()
if "quit" == userInput:
done = True
elif "ls" == userInput:
ls()
else:
string = userInput.split(' ', 1)
if (string[0] == 'put'):
put(userInput)
elif (string[0] == 'get'):
get(userInput)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.close()
print "Closing connection."
And server code:
import socket
import os
import sys
host = ''
port = 8082
backlog = 5
size = 1024
serverID = socket.gethostbyname(socket.gethostname())
info = 'SERVER ID: {} port: {}'.format(serverID, port)
print info
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
done = False
#Loop until client sends 'quit' to server
while not done:
client, address = s.accept()
data = client.recv(size)
print "Server received: ", data
if data:
client.send("Server Says... " + data)
if data == "quit":
done = True
elif data == "ls":
data = os.listdir('c:\\') # listing contents of c: drive
client.send(str(data))
print data
else:
string = data.split(' ', 1)
data_file = string[1]
if (string[0] == 'put'):
with open(data_file, 'wb') as file_to_write: # opening sent filename to write bytes
while True:
data = client.recv(1024)
if not data:
break
file_to_write.write(data) # writing data
file_to_write.close() # closing file
break
print 'Receive Successful'
elif (string[0] == 'get'):
with open('C:\\' + data_file, 'rb') as file_to_send:
for data in file_to_send:
client.send(data)
print 'Send Successful'
client.close()
s.close()
print "Server exiting."

Resources