Skip to content

Instantly share code, notes, and snippets.

@MayankFawkes
Last active August 5, 2020 18:19
Show Gist options
  • Save MayankFawkes/66d2330e9510c609860393f4c3f29392 to your computer and use it in GitHub Desktop.
Save MayankFawkes/66d2330e9510c609860393f4c3f29392 to your computer and use it in GitHub Desktop.
Simple Python Socket | TCP File Sharing Server | python3 FileServer.py server/client 127.0.0.1 4545
'''
Simple file sharing server
'''
import glob, os, sys
import socket, json
import threading
import select
__author__="Mayank Gupta"
__version__="1.1"
class Server:
def __init__(self,host,debug=True):
self.host=host
self.debug=debug
self._connect()
def _connect(self):
if self.debug:print(f"[+]Connecting socket")
self.sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.sock.bind(self.host)
if self.debug:print(f"[+]Socket Listening at {self.host[0]}:{self.host[1]}")
self.sock.listen(5)
self._accept()
def _accept(self):
while True:
conn, address =self.sock.accept()
threading.Thread(target=self._worker,args=(conn,address)).start()
def _worker(self,conn:object,addr:tuple):
if self.debug:print(f"[~][{addr[0]}:{addr[1]}] Connected")
try:
while True:
what=conn.recv(2048).decode("ascii").split()
if what[0].lower()=="ls":
if self.debug:print(f"[~][{addr[0]}:{addr[1]}] Sending ls files")
conn.send(str(self.get_files()).encode("ascii"))
if self.debug:print(f"[~][{addr[0]}:{addr[1]}] ls files sent")
elif what[0].lower()=="download":
if self.check_file(check=what[1]):
conn.send("True".encode("ascii"))
self._download(conn,addr,what[1])
else:conn.send("False".encode("ascii"))
else:
if self.debug:print(f"[~][{addr[0]}:{addr[1]}] invalid command")
conn.send("command not found".encode("ascii"))
except:
print(f"[~][{addr[0]}:{addr[1]}] Disconnected")
@staticmethod
def _download(conn:object,addr:tuple,filename:str)->None:
print(f"[~][{addr[0]}:{addr[1]}] Sending File: {filename}")
with open(filename,"rb") as file:
while True:
data=file.read(8192)
if not data:break
conn.send(data)
conn.send(b"done")
print(f"[~][{addr[0]}:{addr[1]}] File: {filename} sent successfully")
def get_files(self):
file=[]
for infile in glob.glob("*"):
file.append([infile,os.path.getsize(infile)/1024])
return json.dumps(file)
@staticmethod
def check_file(check:bool=False):
if check:
if check in glob.glob("*"):
return True
return False
class Client():
def __init__(self,host):
self.host=host
self._connect()
def _connect(self):
self.sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.sock.connect(self.host)
self._terminal()
def _terminal(self):
while True:
cmd=input(f"Server@{self.host[0]}:~$")
if "ls"==cmd[:2]:
self.sock.send(cmd.encode("ascii"))
what=self.sock.recv(2048).decode("ascii")
what=json.loads(what)
for n in what:
print(f"{n[0]:<40} {n[1]:.2f} KB")
elif "download" == cmd[:8]:
self.sock.send(cmd.encode("ascii"))
what=self.sock.recv(2048).decode("ascii")
if what=="True":
self._save(self.sock,cmd.split()[1])
else:
print(f"{cmd.split()[1]}: No such file")
@staticmethod
def _save(conn,filename):
with open(filename,"wb") as file:
while True:
triple = select.select([conn], [], [], 2)[0]
if not len(triple):break
if conn in triple:
what=conn.recv(8192)
file.write(what)
file.close()
if __name__ == '__main__':
classes={"server":Server,"client":Client}
host=sys.argv[2],int(sys.argv[3])
classes[sys.argv[1]](host)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment