网络编程(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()
原文地址:https://www.cnblogs.com/wanchenxi/p/7746944.html