Im doing a project where it connect to a server directory and read all their files.
So i just wrote a code to download the server files whenever i click on it. I can read small size file with no issues, but when i want to view a large content, only 1 line can be view and store to a list. Although i cant read all the large content, but im able to download it with no issues.
I can read and download all small size content with no issues:
The large file that i want to read from:
Output that i got when i read the large files. (Cant read all the content but i successfully to download the full content file)
CLIENT CODE:
def mouseHover(event):
x = lbox.curselection()[0]
file = lbox.get(x)
ext = (".txt", ".csv")
if file.endswith(ext):
self.s.send(("fdown~" + file).encode("utf-8")) #must have
data = self.s.recv(1024).decode("utf-8")
if data[:6] == 'EXISTS':
filesize = data[6:]
self.s.send("OK".encode("utf-8"))
f = open(file, 'wb') # must have
data = (self.s.recv(1024))
totalRecv = len(data)
f.write(data)
while int(totalRecv) < int(filesize):
data = self.s.recv(1024)
totalRecv += len(data)
f.write(data)
sys.stdout.write("\r|" + "█" * int((totalRecv / float(filesize)) * 50) + "|{0:.2f}".format(
(totalRecv / float(filesize)) * 100) + "% ")
sys.stdout.flush()
time.sleep(0.01)
print("\nDownload Complete!")
f.close()
global data2
data2= data.splitlines()
print(data2)
self.text.delete('1.0', tk.END)
self.text.insert(tk.END, data)
else:
messagebox.showinfo("WARNING", "Currently only .txt/csv file is supported.")
lbox.bind("<<ListboxSelect>>", mouseHover)
SERVER CODE:
# Create a Socket ( connect two computers)
def create_socket():
try:
global host
global port
global s
host = ""
port = 9999
s = socket.socket()
except socket.error as msg:
create_socket()
# Binding the socket and listening for connections
def bind_socket():
try:
global host
global port
global s
s.bind((host, port))
s.listen(5)
except socket.error as msg:
bind_socket()
# send file list
def flist(conn):
try:
arr = pickle.dumps(os.listdir())
conn.send(arr)
except:
conn.send(('Error').encode("utf-8"))
# accept file from server
def fdown(filename, conn):
try:
data = conn.recv(1024).decode("utf-8")
if data[:6] == 'EXISTS':
filesize = data[6:]
conn.send("OK".encode("utf-8"))
f = open(filename, 'wb')
data = (conn.recv(1024))
totalRecv = len(data)
f.write(data)
while int(totalRecv) < int(filesize):
data = conn.recv(1024)
totalRecv += len(data)
f.write(data)
f.close()
except:
conn.send(('Error').encode("utf-8"))
# send file
def fup(filename, conn):
if os.path.isfile(filename):
conn.send(str.encode("EXISTS " + str(os.path.getsize(filename))))
filesize = int(os.path.getsize(filename))
userResponse = conn.recv(1024).decode("utf-8")
if userResponse[:2] == 'OK':
with open(filename, 'rb') as f:
bytesToSend = f.read(1024)
conn.send(bytesToSend)
totalSend = len(bytesToSend)
while int(totalSend) < int(filesize):
bytesToSend = f.read(1024)
totalSend += len(bytesToSend)
conn.send(bytesToSend)
else:
conn.send("ERROR".encode("utf-8"))
# main
def main(s):
while True:
data = (s.recv(1024)).decode("utf-8").split('~')
if data[0] == 'fdown':
fup(data[1], s)
elif data[0] == 'fup':
fdown(data[1], s)
elif data[0] == 'flist':
flist(s)
break
else:
s.send(".".encode('utf-8'))
# Establish connection with a client (socket must be listening)
def socket_accept():
conn, address = s.accept()
main(conn)
conn.close()
create_socket()
bind_socket()
socket_accept()
After you read each block of data, concatenate it to a string containing the whole file. Then at the end of the loop you can split this into lines and display it in the text box.
There's also no need to limit your recv() calls to 1000 bytes. Use filesize - totalRecv as the limit, and it will receive as much as is available, but not go past the end of the file.
There's no need to convert filesize to int every time through the loop, do it once when you assign the variable.
def mouseHover(event):
x = lbox.curselection()[0]
file = lbox.get(x)
ext = (".txt", ".csv")
if file.endswith(ext):
self.s.send(("fdown~" + file).encode("utf-8")) #must have
data = self.s.recv(1024).decode("utf-8")
if data[:6] == 'EXISTS':
filesize = int(data[6:])
self.s.send("OK".encode("utf-8"))
all_data = ''
with open(file, 'wb') as f: # must have
totalRecv = 0
while totalRecv < filesize:
data = self.s.recv(filesize - totalRecv)
totalRecv += len(data)
all_data += data
f.write(data)
sys.stdout.write("\r|" + "█" * int((totalRecv / filesize) * 50) + "|{0:.2f}".format(
(totalRecv / filesize) * 100) + "% ")
sys.stdout.flush()
time.sleep(0.01)
print("\nDownload Complete!")
global data2
data2= all_data.splitlines()
print(data2)
self.text.delete('1.0', tk.END)
self.text.insert(tk.END, all_data)
else:
messagebox.showinfo("WARNING", "Currently only .txt/csv file is supported.")
lbox.bind("<<ListboxSelect>>", mouseHover)
Related
I have a client that let user to browse a file and upload to a server. Currently I'm just using command terminal to operate the program. When user type in fup in the terminal , the program will ask for filename and the file will be upload to the server if the filename input by user is valid.
So, what i want now is letting user to browse any file directory from a GUI without typing the filename to upload. I've tried to implement filedialog but it seem like not working, when i browse and upload a file, the server does not received any new file. I stucked with issues almost a week already but still couldn't find any solution, hope someone could help me. Thanks in advance
Client.py
import socket, sys, os
import time, shutil
# socket creating
def sock():
try:
s = socket.socket()
host = input('Enter Target IP :')
port = 9999
s.connect((host, port))
return (host, s)
except:
print("Error: In binding")
sock()
host, s = sock()
# upload file to client
def fup(conn):
try:
filename = input("\nMANO >>Filename? -> ")
if os.path.isfile(filename):
conn.send(str("fup~" + filename).encode("utf-8"))
conn.send(str.encode("EXISTS " + str(os.path.getsize(filename))))
filesize = int(os.path.getsize(filename))
userResponse = conn.recv(1024).decode("utf-8")
if userResponse[:2] == 'OK':
with open(filename, 'rb') as f:
bytesToSend = f.read(1024)
conn.send(bytesToSend)
totalSend = len(bytesToSend)
while int(totalSend) < int(filesize):
bytesToSend = f.read(1024)
totalSend += len(bytesToSend)
conn.send(bytesToSend)
sys.stdout.write("\r|" + "█" * int((totalSend / float(filesize)) * 50) + "|{0:.2f}".format(
(totalSend / float(filesize)) * 100) + "% ")
sys.stdout.flush()
print("\nUpload Completed!")
else:
print("File Does Not Exist!")
except:
print("Error")
# download file from client
def fdown(conn):
try:
print(os.getcwd())
filename = input("\nMANO >>Filename? -> ")
if filename != 'q':
conn.send(("fdown~" + filename).encode("utf-8"))
data = conn.recv(1024).decode("utf-8")
if data[:6] == 'EXISTS':
filesize = data[6:]
msg = input("File exists, " + str(filesize) + "Bytes, download? (Y/N)? -> ").upper()
if msg == 'Y':
conn.send("OK".encode("utf-8"))
f = open(filename, 'wb')
data = (conn.recv(1024))
totalRecv = len(data)
f.write(data)
while int(totalRecv) < int(filesize):
data = conn.recv(1024)
totalRecv += len(data)
f.write(data)
sys.stdout.write("\r|" + "█" * int((totalRecv / float(filesize)) * 50) + "|{0:.2f}".format(
(totalRecv / float(filesize)) * 100) + "% ")
sys.stdout.flush()
time.sleep(0.01)
print("\nDownload Complete!")
f.close()
else:
print("File Does Not Exist!")
except:
print("Error")
# commands that perform on client
def mano(cip, conn):
while True:
cli = input("MANO >>" + cip + ' >>')
if cli == 'fdown':
fdown(conn)
elif cli == 'fup':
fup(conn)
else:
print("Command not recognized")
mano(host, s)
Server.py
import socket, os, subprocess, shutil, pickle, struct, threading
## gettig the hostname by socket.gethostname() method
hostname = socket.gethostname()
## getting the IP address using socket.gethostbyname() method
ip_address = socket.gethostbyname(hostname)
# Create a Socket ( connect two computers)
def create_socket():
try:
global host
global port
global s
host = ""
port = 9999
s = socket.socket()
except socket.error as msg:
create_socket()
# Binding the socket and listening for connections
def bind_socket():
try:
global host
global port
global s
s.bind((host, port))
s.listen(5)
## printing the hostname and ip_address
print(f"Hostname: {hostname}")
print(f"IP Address: {ip_address}")
print(f"Running Port: {port}")
except socket.error as msg:
bind_socket()
print(bind_socket())
# send file list
def flist(conn):
try:
arr = pickle.dumps(os.listdir())
conn.send(arr)
print(arr)
except:
conn.send(('Error').encode("utf-8"))
# accept file from server
def fdown(filename, conn):
try:
data = conn.recv(1024).decode("utf-8")
if data[:6] == 'EXISTS':
filesize = data[6:]
conn.send("OK".encode("utf-8"))
f = open(filename, 'wb')
data = (conn.recv(1024))
totalRecv = len(data)
f.write(data)
while int(totalRecv) < int(filesize):
data = conn.recv(1024)
totalRecv += len(data)
f.write(data)
f.close()
except:
conn.send(('Error').encode("utf-8"))
# send file
def fup(filename, conn):
if os.path.isfile(filename):
conn.send(str.encode("EXISTS " + str(os.path.getsize(filename))))
filesize = int(os.path.getsize(filename))
userResponse = conn.recv(1024).decode("utf-8")
if userResponse[:2] == 'OK':
with open(filename, 'rb') as f:
bytesToSend = f.read(1024)
conn.send(bytesToSend)
totalSend = len(bytesToSend)
while int(totalSend) < int(filesize):
bytesToSend = f.read(1024)
totalSend += len(bytesToSend)
conn.send(bytesToSend)
else:
conn.send("ERROR".encode("utf-8"))
# main
def main(s):
while True:
data = (s.recv(1024)).decode("utf-8").split('~')
if data[0] == 'fdown':
fup(data[1], s)
elif data[0] == 'fup':
fdown(data[1], s)
elif data[0] == 'flist':
flist(s)
else:
s.send(".".encode('utf-8'))
def socket_accept():
while True:
conn, address = s.accept()
t = threading.Thread(target=main, args=(conn,))
t.start()
create_socket()
bind_socket()
socket_accept()
Expected output:
since you are using a gui I think you should receive the inputs through the use of an tkinter.Entry widget not through the terminal with input()
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.
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.
File Server Download Problem Python 2.5.1
So i am working on a File Server as a hobby project. I am having some problems though. I can use the client to successfully upload the file to the server but say the file to upload is 50,000 bytes (50 mbs) it will only upload like 49,945 bytes then if i try opening it, it says its corrupt. If i close the server it goes to 50,000 then works. Is there a way to fix this without the server needing to close and reopen?
(Downloading Doesnt Have this Problem)
Full Client Code:
Client
Full Server:
Server
Client Upload Function:
def Uploader(s):
IsReal = True
data = "UploaderReady"
if data == "UploaderReady":
List = []
FilePath = dir_path = os.path.dirname(os.path.realpath(__file__))
List.append(os.listdir(FilePath))
FileUpload = raw_input("Pick a file? -> ")
for Item in List:
if FileUpload == Item:
IsReal = True #checks if item exists
if IsReal == True:
File = open(FileUpload,'rb')
bytestosend = File.read(1024)
FileSize = os.path.getsize(FileUpload)
s.send(FileUpload)
s.send(str(FileSize))
s.send(bytestosend)
while bytestosend != "":
bytestosend = File.read(8192)
s.send(bytestosend)
print"Processing"
File.close()
time.sleep(1.5)
s.send("COMPLETE")
print"File Successfully Uploaded"
time.sleep(2)
print" \n " * 10
Main()
if IsReal == "False":
print"Item doesn't Exist"
time.sleep(2)
print" \n " * 10
s.close()
Main()
Server Upload Function:
Todo = sock.recv(1024)
if Todo == "U":
print str(addr)+" Uploading"
UploadingThread = threading.Thread(target=Uploader,args=(c,c,))
UploadingThread.start()
def Uploader(c,s):
filename = s.recv(1024)
filesize = s.recv(1024)
f = open(filename,'wb')
totalRecv = 0
while totalRecv < filesize:
FileContent = s.recv(8192)
totalRecv += len(FileContent)
f.write(FileContent)
print"Download Complete"
f.close()
s.close()
You close the client connection on the server side, but never close it on the client side as Cory Shay said.
Instead of closing it though, you need to shutdown the socket and signal it is done writing with s.shutdown(socket.SHUT_WR)
Here's how it should look for the client:
def Uploader(s):
IsReal = True
data = "UploaderReady"
if data == "UploaderReady":
List = []
FilePath = dir_path = os.path.dirname(os.path.realpath(__file__))
List.append(os.listdir(FilePath))
FileUpload = raw_input("Pick a file? -> ")
for Item in List:
if FileUpload == Item:
IsReal = True #checks if item exists
if IsReal == True:
File = open(FileUpload,'rb')
bytestosend = File.read(1024)
FileSize = os.path.getsize(FileUpload)
s.send(FileUpload)
s.send(str(FileSize))
s.send(bytestosend)
while bytestosend != "":
bytestosend = File.read(8192)
s.send(bytestosend)
print"Processing"
s.shutdown(socket.SHUT_WR) # End the writing stream
print(s.recv(1024)) # Expecting the server to say 'upload complete'
s.close() # close the socket
File.close()
time.sleep(1.5)
s.send("COMPLETE")
s.close() #To close connection after uploading
print"File Successfully Uploaded"
time.sleep(2)
print" \n " * 10
Main()
and the server:
def Uploader(c,s):
filename = s.recv(1024)
filesize = s.recv(1024)
f = open(filename,'wb')
totalRecv = 0
while totalRecv < filesize:
FileContent = s.recv(8192)
totalRecv += len(FileContent)
f.write(FileContent)
s.send("Upload Complete!") # Tell client the upload is complete
print"Download Complete"
f.close()
s.close() # Close the socket
Also, you are passing the server Uploader 2 identical arguments, and only using one, instead you should just pass one:
UploadingThread = threading.Thread(target=Uploader,args=(c,c,))
# should be
UploadingThread = threading.Thread(target=Uploader,args=(c,))
Similarly, your password thread only needs 2:
c, addr = s.accept()
print"Client Connection: <"+str(addr)+">"
PasswordThread = threading.Thread(target=Password,args=(c,addr))
def Password(c,addr):
c.send("WAITINGPASSWORD")
PASSWORD = "123"
password = c.recv(1024)
and your checking password function can be simpler:
def Password(c,addr):
password = "123"
c.send("WAITINGPASSWORD")
attempt = c.recv(1024)[::-1]
if attempt == password:
doStuff()
trying out a new way to send files. The client will be run every 10 mins to ask server to send what's new in last 10 mins. What I have so far work 40% of the time. I can't figure out so far why that is the case.
server main loop:
while 1:
conn, addr = s.accept()
last_ai = get_last_sent_ai()
new_ai = get_new_ai(last_ai)
ai_notes = ''
''' send # of file '''
print "sending length ---------"
conn.sendall('{0}'.format(len(new_ai)))
for ai_file in new_ai:
ai_file = ai_file.rstrip()
if not os.path.isfile(ai_file): continue
f = open(ai_file, 'rb')
ai_notes = f.read()
f.close()
print "sending file infor " + '{0:<10d}:{1:>40s}'.format(len(ai_notes), ai_file)
ready_flag = conn.recv(5)
if ready_flag == "Ready":
conn.sendall(ai_notes)
if len(new_ai) > 0:
update_last_sent(new_ai[-1])
else:
print 'nothing to send'
conn.sendall(' ')
conn.close()
s.close()
Client main loop:
if num_f == 0: sys.exit(0)
while num_f > 0:
f_info = ''
f_info = s.recv(50)
f_len,f_name_tmp = f_info.split(':')
f_len = int(f_len)
s.sendall("Ready")
f_name = f_name_tmp
f = open(f_name, 'wb')
recvd = 0
while recvd < f_len:
chunk = s.recv(min(f_len - recvd, 1024))
if chunk == '':
raise RuntimeError("socket connection broken")
f.write(chunk)
recvd = recvd + len(chunk)
f.close()
num_f -= 1
s.close()
update:
the issue seems to be gone after I went back and changed how the send and receive are done. There gotta be some kind of blocking going on when it hangs, so I followed the python doc and modified the code and all the tests so far are working.