ftp server
#!/usr/bin/python3
# hello.py
import os, sys
from socket import *
import signal as sig
import time
ADDR = ('127.0.0.1', int(sys.argv[1]))
BUFFERSIZE = 1024
FILEPATH = './hello/'
def search_file(obj):
for root, dirs, files in os.walk(FILEPATH, topdown=False):
for name in files:
if name==obj:
print('get %s sucess'%obj)
return os.path.join(root, name)
return False
def handle(cli):
addr = cli.getpeername()
#split command(command, filename, option)
#opt to use, e.g.: -f: force exec, new file cover old file!
cmd = cli.recv(BUFFERSIZE).decode('utf-8').split()
obj = None
opt = None
if len(cmd)==1:
cmd = cmd[0]
if cmd == 'q':
cli.close()
sys.exit(str(addr)+ 'logout')
elif len(cmd)==2:
cmd,obj = cmd
elif len(cmd)==3:
cmd, obj, opt = cmd
#execute command
if cmd == 'l':# use 'tree' command to show dirs and files
msg = os.popen('tree '+FILEPATH)
msg = msg.read().encode('utf-8')
cli.send(msg)
return
elif cmd == 'g':# get file from server to cli
if obj is None:
cli.send(b'g need filename')
return
else:# file exist or not, res is file's path&name
res = search_file(obj)
if res:
cli.send(b'ok! file exist!')
time.sleep(0.1)# wait
try:
with open(res, 'rb') as fp:
while True:
data = fp.read(BUFFERSIZE)
if not data:
break
cli.send(data)
# sucessfully send, all content or unfortunately, part of the file, with Exception catched all kinds of errors
time.sleep(0.1)
cli.send(b'EOF')# add EOF at the end of the file data
except Exception as e:
print(e)
print('send sucess')
return
else:
cli.send(b'bad, file not exist...')
return
elif cmd =='p':
if obj is None:
cli.send(b'p need filename')
return
elif not search_file(obj):
cli.send(b'ok to upload')# file not exit, you can upload
try:
with open(FILEPATH+obj, 'wb') as fp:
while True:
data = cli.recv(BUFFERSIZE)
if data == b'EOF':
print('up ok!')
break
fp.write(data)
except Exception as e:
print('write error',e)
print('finished')
elif opt is None:
cli.send(b"already exist, are you sure? you can use '-f'")
else:
if opt == '-f':
cli.send(b'ok to upload')
try:
with open(FILEPATH+obj, 'wb') as fp:
while True:
data = cli.recv(BUFFERSIZE)
if data == b'EOF':
print('up ok!')# get end sign of file
break
fp.write(data)
except Exception as e:
print('write error',e)
print('finished')
else:
return
def main():
ftp = socket()
ftp.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
ftp.bind(ADDR)
ftp.listen(5)
sig.signal(sig.SIGCHLD, sig.SIG_IGN)
while True:
try:
cli, addr = ftp.accept()
except KeyboardInterrupt:
ftp.close()
sys.exit('ftp server exit')
except Exception as e:
print(e)
continue
print('connect from', addr)
pid = os.fork()
if pid < 0:
print('create process failed')
continue
elif pid == 0:
ftp.close() #??
print('handle cli event...')
while True:
handle(cli)
else:
#cli.close()??
continue
if __name__ == "__main__":
main()
client
#!/usr/bin/python3
# hello.py
from socket import *
import sys
import time
ADDR = ('127.0.0.1', int(sys.argv[1]))
BUFFERSIZE = 1024
FILEPATH = './world/'
def handle(ftp, cmd):
if cmd[:1] == 'l':
ftp.send(b'l')
msg = ftp.recv(BUFFERSIZE).decode('utf-8')
print(msg)
elif cmd[:1] =='p':
ftp.send(cmd.encode('utf-8'))
msg = ftp.recv(BUFFERSIZE).decode('utf-8')
print(msg)
if msg.startswith('ok'):
try:
with open(FILEPATH+cmd.split()[1], 'rb') as fp:
while True:
data = fp.read(BUFFERSIZE)
if not data:
break
ftp.send(data)
# sucessfully send, all content or unfortunately, part of the file, with Exception catched all kinds of errors
time.sleep(0.1)# add EOF at the end of the file data
ftp.send(b'EOF')
except Exception as e:
print(e)
elif msg.startswith('already'):
return
elif cmd[:1] == 'g':
ftp.send(cmd.encode('utf-8'))
msg = ftp.recv(BUFFERSIZE).decode('utf-8')
print(msg)
if msg.startswith('ok'):# file exists in server
name = cmd.split()[1]
try:
with open(FILEPATH+name, 'wb') as fp:
while True:
data = ftp.recv(BUFFERSIZE)
if data == b'EOF':# get end sign of file
print('down ok!')
break
fp.write(data)
except Exception as e:
print('write error:',e)
print('finished')
elif cmd[:1] == 'q':
ftp.close()
sys.exit('exit')
else:
return
def main():
ftp = socket()
try:
ftp.connect(ADDR)
except Exception as e:
sys.exit(e)
print('*****COMMAND**IS**LGPQ*****')
while True:
addr = ftp.getsockname()
cmd = input(str(addr[1])+'$ ')
handle(ftp, cmd)
ftp.close()
if __name__ == "__main__":
main()
已实现功能:
1. 使用命令长传下载文件:
2. 展示文件目录和文件,
3. 附加命令选项,-f覆盖原文件上传