Server:
#!/usr/bin/python
#coding:utf-8
#定义一个类继承socketserver.BaseRequestHandler
#重写handle方法,所有通讯由他处理
#实例化socketserver = socketserver.TCPServer((HOST,PORT),MyTCPHandler)
import socketserver #导入socket服务模块
import json,os
class MyTCPHandler(socketserver.BaseRequestHandler):#继承socketserver.BaseRequestHandler
def handle(self):
while True:# 让客户端的连接重复接收,直到自己断开
try:
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0])) # 打印连接的地址
print(self.data) # 输出接收的内容
cmd_dic = json.loads(self.data.decode())
action = cmd_dic["action"]
if hasattr(self,action):
func = getattr(self,action)
func(cmd_dic)
except ConnectionResetError as co:
print(co,'连接断开了')
break
def put(self,*args):
'''接收客户端文件'''
cmd_dic = args[0]
filename = cmd_dic["filename"]
filesize = cmd_dic["size"]
if os.path.isfile(filename):
f = open(filename+'.new',"wb")#文件存在,就换个名字
else:
f = open(filename, "wb")#文件不存在,新建一个文件
self.request.send(b'200 ok')
received_size = 0
while received_size < filesize:
data = self.request.recv(1024)
f.write(data)
received_size += len(data)
else:
print("file [%s] has uploaded..."%filename)
if __name__ == "__main__":
HOST, PORT = "localhost", 8888
#server = socketserver.TCPServer((HOST,PORT),MyTCPHandler) #单并发
#server = socketserver.ForkingTCPServer((HOST,PORT),MyTCPHandler) #多进程并发,和多线程效果一样(只能在linux上使用,windows上面fork不一样无法使用)
server = socketserver.ThreadingTCPServer((HOST,PORT),MyTCPHandler) #多线程并发
#server.handle_request()#处理单个请求
server.serve_forever()#处理多个请求,永远执行,直到收到shutdown(),才会结束
Client:
#!/usr/bin/python
#coding:utf-8
import socket
import os
import json
class FtpClient(object):
def __init__(self):
self.client = socket.socket() # 声明一个socket类型,同时生成对象
def help(self):
msg='''ls
pwd
df
cd ../..
get filename
put filename
'''
print(msg)
def connect(self,ip,port):#连接 服务器端
#selt.authrenzheng() 这里应该写个用户认证,通过了才能去连接服务端
self.client.connect((ip,port))
def interactive(self):#连上后和server交互
while True:
cmd = input(">>")
if len(cmd) == 0:continue
cmd_str = cmd.split()[0]
#print(cmd_str,'=====')
if hasattr(self,"cmd_%s"%cmd_str):
#print("cmd_%s"%cmd_str)
func = getattr(self,"cmd_%s"%cmd_str)
func(cmd)
else:
self.help()
def cmd_put(self,*args):
cmd_split = args[0].split()
if len(cmd_split) >1:
filename = cmd_split[1] #获取文件名
if os.path.isfile(filename):#是文件
filesize = os.stat(filename).st_size #获取文件大小
msg_dic = {
"action":"put",
"filename":filename,
"size":filesize,
"overridden":True
}#socket只能传bytes,因此需要json持久化成字符串
self.client.send(json.dumps(msg_dic).encode('utf-8'))# 先存储成json数据,在encode成bytes字节
#防止粘包,等服务器确认
server_response = self.client.recv(1024)
#发送文件
f = open(filename,'rb')
for line in f:
self.client.send(line)
else:
print("file upload sucess。。。。。")
f.close()
else:
print(filename,"is noe exist")
def cmd_get(self,cmd):
print('cmd_get',cmd)
pass
FTP = FtpClient()
FTP.connect("localhost",8888)
FTP.interactive()