Python学习之socket上传文件

#服务器
import socketserver,json,os

class MyTCPHandler(socketserver.BaseRequestHandler):
    # handle()
    # 执行完就断开,处理和客户端的所有交互
    def put(self,*args):
        #接受客户端文件
        cmd_dic = args[0] # 传进来的是 字典cmd_dic
        # print(cmd_dic)
        # b‘{"action": "put", "filename": "2.py", "size": 2240, "overridden": true}‘
        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)


    def handle(self):
        while True:
            try:
                # self.request is the TCP socket connected to the client
                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 e:
                print("error:",e)
                break
if __name__ == "__main__":
    HOST, PORT = "localhost",9999
    # Create the server, binding to localhost on port 9999
    #server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
    # 每来一个请求,开启一个新的线程
    # 换成下面这个,就可以多并发了,这样,客户端每连进一个来,
    # 服务器端就会分配一个新的线程来处理这个客户端的请求
    server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
    # Activate the server; this will keep running until you
    # interrupt the program with Ctrl-C
    server.serve_forever()
#客户端
#!/usr/bin/env python
#-*-coding:utf8-*-

import socket,struct,hashlib,os,json


class FtpClient(object):
    def __init__(self):
        self.client = socket.socket()

    def help(self):
        msg=‘‘‘
        ls
        pwd
        cd ../..
        get filename
        put filename
        ‘‘‘
    def connect(self,ip,port):
        self.client.connect((ip,port))

    def interactive(self):
        #self.authencate()
        while True:
            cmd = input(">>:").strip()
            if len(cmd) ==0:continue
            cmd_str = cmd.split()[0] #split第一个是指令,即get/put
            if hasattr(self,"cmd_%s" %cmd_str):
                func = getattr(self,"cmd_%s"%cmd_str) #取得put的内存地址
                func(cmd) #调用put()函数 ,cmd == put 2.py,用split分开
            else:
                self.help()

    def cmd_put(self,*args):
        cmd_split = args[0].split() # cmd_split == put 2.py,是一个列表
        print(args[0].split())
        if len(cmd_split) > 1: #如果只写了put就不执行
            filename = cmd_split[1]  #取出 文件名   2.py
            if os.path.isfile(filename):
                filesize = os.stat(filename).st_size
                msg_dic={
                    "action":"put",
                    "filename":filename,
                    "size":filesize,
                    "overridden":True
                }
                #socket只能传bytes形式
                self.client.send( json.dumps(msg_dic).encode("utf-8"))
                print("send",json.dumps(msg_dic).encode("utf-8"))
                #防止粘包,等服务器确认
                server_reponse = self.client.recv(1024)
                print(server_reponse)
                #服务器应该去判断是否有空间存放或者文件是否存在,
                #回复客户端

                f = open(filename,"rb")
                for line in f:
                    self.client.send(line)
                else:
                    print("file upload success")

            else:
                print(filename,"is not exist")

    def cmd_get(self):
        pass

ftp = FtpClient()
ftp.connect("localhost",9999)
ftp.interactive()

相关推荐