客户端代码如下:
from socket import *
import sys
import time
class FtpClient(object):
def init(self,sockfd):
self.sockfd = sockfd
def do_list(self):
#发送请求
self.sockfd.send(b’L’)
#等待回复
data = self.sockfd.recv(1024).decode()
if data == “OK”:
data = self.sockfd.recv(4096).decode()
files = data.split(“#”)
for file in files:
print(file)
print(“文件列表展示完毕\n”)
else:
#服务器发送失败原因
print(data)
def do_get(self,filename):
self.sockfd.send(b’G’ + filename.encode())
data = self.sockfd.recv(1024).decode()
if data == ‘OK’:
fd = open(filename,’wb’)
while True:
data = self.sockfd.recv(1024)
if data == b’##’:
break
fd.write(data)
fd.close()
print(“%s 下载完成\n”%filename)
else:
print(data)
def do_quit(self):
self.sockfd.send(b”Q”)
def main():
if len(sys.argv) < 3:
print(“argv is error”)
return
HOST = sys.argv[1]
PORT = int(sys.argv[2])
ADDR = (HOST,PORT) #文件服务器地址
#创建套接字
sockfd = socket()
try:
sockfd.connect(ADDR)
except:
print(“连接服务器失败”)
return
ftp = FtpClient(sockfd) #功能类对象
while True:
print(“==========命令选项==========”)
print(“** list **“)
print(“** get list ”)
print(“** put list ”)
print(“** quit **“)
print(“==========================”)
cmd = input("请输入命令:")
if cmd.strip() == 'list':
ftp.do_list()filename
elif cmd[0:3] == 'get':
filename = cmd.split(' ')[-1]
ftp.do_get(filename)
elif cmd.strip() == 'put list':
pass
elif cmd.strip() == 'quit':
ftp.do_quit()
sockfd.close()
sys.exit("谢谢使用")
else:
print("请输入正确的命令!!!")
if name == “main“:
main()
服务端代码如下:
from socket import *
import os
import sys
import time
import signal
FILE_PATH = “/home/tarena/ftpFile/”
HOST = ‘0.0.0.0’
PORT = 8888
ADDR = (HOST,PORT)
class FtpServer(object):
def init(self,connfd):
self.connfd = connfd
def do_list(self):
#获取文件列表
file_list = os.listdir(FILE_PATH)
if not file_list:
self.connfd.send(“文件库为空”.encode())
else:
self.connfd.send(b’OK’)
time.sleep(0.1)
files = “”
for file in file_list:
if file[0] != ‘.’ and os.path.isfile(FILE_PATH + file):
files = files + file + ‘#’
self.connfd.sendall(files.encode())
def do_get(self,filename):
try:
open(FILE_PATH + filename,’rb’)
except:
self.connfd.send(‘文件不存在’.encode())
self.connfd.send(b”OK”)
time.sleep(0.1)
#发送文件
while True:
data = fd.read(1204)
if not data:
time.sleep(0.1)
self.connfd.send(b’##’)
break
self.connfd.send(data)
print(‘文件发送完毕!!!’)
def main():
sockfd = socket()
sockfd.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
sockfd.bind(ADDR)
sockfd.listen(5)
#处理子进程退出
signal.signal(signal.SIGCHLD,signal.SIG_IGN)
print("Listen the port 8888....")
while True:
try:
connfd,addr = sockfd.accept()
except KeyboardInterrupt:
sockfd.close()
sys.exit("服务器退出")
except Exception as e:
print("服务器异常",e)
continue
print("已连接客服端")
#创建子进程
pid = os.fork()
if pid == 0:
sockfd.close()
ftp = FtpServer(connfd)
#判断客服端请求
while True:
data = connfd.recv(1024).decode()
if not data:
connfd.close()
sys.exit('客服端退出')
elif data[0] == "L":
ftp.do_list()
elif data[0] == 'G':
filename = data.split(" ")[-1]
ftp.do_get(filename)
elif data[0] == 'Q':
connfd.close()
sys.exit('客服端退出')
else:
connfd.close()
continue
if name == “main“:
main()