zoukankan      html  css  js  c++  java
  • socketserver 模块实现ftp功能

    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()
  • 相关阅读:
    分治
    递归
    java三大特性之封装
    Java基础知识
    puk2367 拓扑排序
    puk1251 最小生成树
    puk1521 赫夫曼树编码
    DOSbox简单运行操作
    Mybatis初学经验----------------(2)
    mysql存储引擎MyISAM和InnoDB的区别
  • 原文地址:https://www.cnblogs.com/jim-xu/p/12293766.html
Copyright © 2011-2022 走看看