python网络编程
程序的目录结构
socketDemo ├── client │ ├── cli.py │ └── local_dir │ └── lianxijiangjie.mp4 └── server ├── download │ └── lianxijiangjie.mp4 └── ser.py
基础版本
ser.py
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'mosson' import socket import struct import json import os base_dir = os.path.dirname(os.path.abspath(__file__)) base_dir = os.path.join(base_dir, 'download') class MYTCPServer: 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 server_dir='file_upload' def __init__(self, server_address, bind_and_activate=True): """Constructor. May be extended, do not override.""" self.server_address=server_address self.socket = socket.socket(self.address_family, self.socket_type) if bind_and_activate: try: self.server_bind() self.server_activate() except: self.server_close() raise def server_bind(self): """Called by constructor to bind the socket. """ if self.allow_reuse_address: self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.socket.bind(self.server_address) self.server_address = self.socket.getsockname() def server_activate(self): """Called by constructor to activate the server. """ self.socket.listen(self.request_queue_size) def server_close(self): """Called to clean-up the server. """ self.socket.close() def get_request(self): """Get the request and client address from the socket. """ return self.socket.accept() def close_request(self, request): """Called to clean up an individual request.""" request.close() def run(self): print('server is running .......') while True: self.conn,self.client_addr=self.get_request() print('from client ',self.client_addr) while True: try: head_struct = self.conn.recv(4) if not head_struct:break head_len = struct.unpack('i', head_struct)[0] head_json = self.conn.recv(head_len).decode(self.coding) head_dic = json.loads(head_json) print(head_dic) cmd=head_dic['cmd'] if hasattr(self,cmd): func=getattr(self,cmd) func(head_dic) except Exception: break def put(self,args): """ 文件长传 :param args: :return: """ file_path=os.path.normpath(os.path.join( base_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.conn.recv(2048) f.write(recv_data) recv_size += len(recv_data) else: print('recvsize:%s filesize:%s' %(recv_size,filesize)) def get(self, args): """ 下载文件 1 检测服务端文件是不是存在 2 文件信息 打包发到客户端 3 发送文件 """ filename = args['filename'] dic = {} if os.path.isfile(base_dir + '/' + filename): dic['filesize'] = os.path.getsize(base_dir + '/' + filename) dic['isfile'] = True else: dic['isfile'] = False str_dic = json.dumps(dic) # 字典转str bdic = str_dic.encode(self.coding) # str转bytes dic_len = len(bdic) # 计算bytes的长度 bytes_len = struct.pack('i', dic_len) # self.conn.send(bytes_len) # 发送长度 self.conn.send(bdic) # 发送字典 # 文件存在发送真实文件 if dic['isfile']: with open(base_dir + '/' + filename, 'rb') as f: while dic['filesize'] > 2048: content = f.read(2048) self.conn.send(content) dic['filesize'] -= len(content) else: content = f.read(2048) self.conn.send(content) dic['filesize'] -= len(content) print('下载完成') tcpserver1=MYTCPServer(('127.0.0.1',8083)) tcpserver1.run()
cli.py
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'mosson' import socket import struct import json import os import time base_dir = os.path.dirname(os.path.abspath(__file__)) base_dir = os.path.join(base_dir, 'local_dir') 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] filename = base_dir + '/' + filename print(filename) 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 t1 = time.time() # with open(filename,'rb') as f: # for line in f: # self.socket.send(line) # send_size+=len(line) # else: # print('upload successful') # t2 = time.time() with open(filename, 'rb') as f: while head_dic['filesize'] > 2048: content = f.read(2048) self.socket.send(content) head_dic['filesize'] -= len(content) else: content = f.read(2048) self.socket.send(content) head_dic['filesize'] -= len(content) t2 = time.time() print(t2-t1) def get(self, args): cmd = args[0] filename = args[1] dic = {'cmd': cmd, 'filename': filename} """发送dic的步骤 字典转str str转bytes 计算bytes的长度 发送长度 发送字典 """ str_dic = json.dumps(dic) # 字典转str bdic = str_dic.encode(self.coding) # str转bytes dic_len = len(bdic) # 计算bytes的长度 bytes_len = struct.pack('i', dic_len) # self.socket.send(bytes_len) # 发送长度 self.socket.send(bdic) # 发送字典 # 接受 准备下载的文件信息 dic_len = self.socket.recv(4) dic_len = struct.unpack('i', dic_len)[0] dic = self.socket.recv(dic_len).decode(self.coding) dic = json.loads(dic) # 文件存在准备下载 if dic['isfile']: t1 = time.time() with open(base_dir+'/'+filename, 'wb') as f: while dic['filesize'] > 2048: content = self.socket.recv(2048) f.write(content) dic['filesize'] -= len(content) else: while dic['filesize']: content = self.socket.recv(2048) f.write(content) dic['filesize'] -= len(content) t2 = time.time() print(t2-t1) else: print('文件不存在!') client=MYTCPClient(('127.0.0.1',8083)) client.run()
升级版本
。。。。。。。。
==================== 码字不易,如有帮助,请多多支持 ====================