• 网络编程(day3)socketserver模块 并发的ftp带上传下载文件功能


    socket 实现并发,记住继承关系的几张图

    基于tcp的套接字,关键就是两个循环,一个链接循环,一个通信循环

    socketserver模块中分两大类:server类(解决链接问题)和request类(解决通信问题)

    客户端没必要变 

    socketserver 模块已经实现多进程,多线程
    客户端没有必要动,服务端要动
    继承必须继承,
    handle方法也是必须的

    http://www.cnblogs.com/linhaifeng/articles/6129246.html#_label14

    server端

    #服务端第一个特点是:
        # 一直运行提供服务(链接循环),(基于一个链接通信循环)
        # 绑定一个唯一的地址
    #
    # import socket
    # phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
    # phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
    # phone.bind(('127.0.0.1',8080)) #绑定手机卡
    #
    # phone.listen(5) #开机  ?5
    #
    # print('starting....')
    # while True: #链接循环
    #     conn,addr=phone.accept() #等待电话链接
    #
    #     print('电话线路是',conn)
    #     print('客户端的手机号是',addr)
    #
    #     while True: #通信循环
    #         try: #应对windows系统
    #             data=conn.recv(1024) #收消息  ?1024
    #             if not data:break #linux系统
    #             print('客户端发来的消息是',data)
    #
    #             conn.send(data.upper())
    #         except Exception:
    #             break
    #
    #     conn.close()
    #
    # phone.close()
    
    
    import socketserver
    
    #Ftpserver(conn, client_addr, obj)
    
    class FTPserver(socketserver.BaseRequestHandler): #通讯
        def handle(self):
            print('=-=====>',self.request)
            print(self.request)
            while True:
                data=self.request.recv(1024)
                print(data)
                self.request.send(data.upper())
    
    
    if __name__ == '__main__':
        obj=socketserver.ThreadingTCPServer(('127.0.0.1',8080),FTPserver)
        print(obj.server_address)
        print(obj.RequestHandlerClass)
        print(obj.socket)
    
        obj.serve_forever() #链接循环

    client端 多开几个

    import socket
    phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    phone.connect(('127.0.0.1',8080))
    
    while True: #通信循环
        msg=input('>>: ').strip()
        if not msg:continue
        phone.send(msg.encode('utf-8'))
        # print('has send===========>')
        data=phone.recv(1024)
        # print('has recv===========>')
        print(data)
    
    phone.close()

    ####################################################################

    ####################################################################

    socketserver模块   并发的ftp带上传下载文件功能

    服务端()

    import socketserver
    import struct
    import json
    import subprocess
    import os
    
    class MYTCPServer(socketserver.BaseRequestHandler):
    
        max_packet_size = 8192
    
        coding='utf-8'
        BASE_DIR=os.path.dirname(os.path.abspath(__file__))
    
        server_dir='file_upload'
    
        def handle(self):
            while True:
                try:
                    head_struct = self.request.recv(4)
                    if not head_struct:break
    
                    head_len = struct.unpack('i', head_struct)[0]
                    head_json = self.request.recv(head_len).decode(self.coding)
                    head_dic = json.loads(head_json)
    
                    print(head_dic)
                    #head_dic={'cmd':'put','filename':'a.txt','filesize':123123}
                    cmd=head_dic['cmd']
                    if hasattr(self,cmd):
                        func=getattr(self,cmd)
                        func(head_dic)
                except Exception:
                    break
    
        def put(self,args):
            file_path=os.path.normpath(os.path.join(
                self.BASE_DIR,
                self.server_dir,
                args['filename']
            ))
    
            filesize=args['filesize']
            recv_size=0
            print('----->',file_path)
            with open(file_path,'wb') as f:
                while recv_size < filesize:
                    recv_data=self.request.recv(self.max_packet_size)
                    f.write(recv_data)
                    recv_size+=len(recv_data)
                    print('recvsize:%s filesize:%s' %(recv_size,filesize))
    
    
    
    
    if __name__ == '__main__':
        obj=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MYTCPServer)
        obj.serve_forever()

    客户端

    import socket
    import struct
    import json
    import os
    
    
    
    class MYTCPClient:
        address_family = socket.AF_INET
    
        socket_type = socket.SOCK_STREAM
    
        allow_reuse_address = False
    
        max_packet_size = 8192
    
        coding='utf-8'
    
        request_queue_size = 5
    
        def __init__(self, server_address, connect=True):
            self.server_address=server_address
            self.socket = socket.socket(self.address_family,
                                        self.socket_type)
            if connect:
                try:
                    self.client_connect()
                except:
                    self.client_close()
                    raise
    
        def client_connect(self):
            self.socket.connect(self.server_address)
    
        def client_close(self):
            self.socket.close()
    
        def run(self):
            while True:
                inp=input(">>: ").strip()
                if not inp:continue
                l=inp.split()
                cmd=l[0]
                if hasattr(self,cmd):
                    func=getattr(self,cmd)
                    func(l)
    
    
        def put(self,args):
            cmd=args[0]
            filename=args[1]
            if not os.path.isfile(filename):
                print('file:%s is not exists' %filename)
                return
            else:
                filesize=os.path.getsize(filename)
    
            head_dic={'cmd':cmd,'filename':os.path.basename(filename),'filesize':filesize}
            print(head_dic)
            head_json=json.dumps(head_dic)
            head_json_bytes=bytes(head_json,encoding=self.coding)
    
            head_struct=struct.pack('i',len(head_json_bytes))
            self.socket.send(head_struct)
            self.socket.send(head_json_bytes)
            send_size=0
            with open(filename,'rb') as f:
                for line in f:
                    self.socket.send(line)
                    send_size+=len(line)
                    print(send_size)
                else:
                    print('upload successful')
    
    
    
    
    client=MYTCPClient(('127.0.0.1',8080))
    
    client.run()
  • 相关阅读:
    数组作为方法参数时的一些意外情况
    pack://application:,,,/
    WPF 使用WinForm Chart控件
    WPF 后台绑定样式
    在转换为 UTC 时大于 DateTime.MaxValue 或小于 DateTime.MinValue 的 DateTime 值无法系列化为 JSON
    LINQ_to_SQL语法及实例大全
    C#编码好习惯,献给所有热爱c#的同学
    C#中OpenFileDialog的使用
    NET 2.0(C#)调用ffmpeg处理视频的方法
    SQLite Mysql 模糊查找(like)
  • 原文地址:https://www.cnblogs.com/wanchenxi/p/7746944.html
Copyright © 2020-2023  润新知