当前位置: 代码迷 >> 综合 >> day8 动态导入模块、socket进阶
  详细解决方案

day8 动态导入模块、socket进阶

热度:20   发布时间:2023-12-25 19:34:49.0

文章目录

  • 1. 动态导入模块
  • 2. socket 进阶

1. 动态导入模块

文件目录如下:
在这里插入图片描述
aa.py 文件中:

class C(object):def __init__(self):self.name = 'yle'

现在 ‘动态导入模块.py’ 中导入 aa.py

import importlibaa = importlib.import_module('lib.aa')print(aa.C().name)

2. socket 进阶

例1:一个执行命令行通信的简易程序如下:

服务端:

import socket,os,timeserver = socket.socket()server.bind(('localhost',9999))server.listen()while True:conn,addr = server.accept()print('new conn',addr)while True:print('等待新指令')data = conn.recv(1024)if not data:print('客户端已断开')breakprint('执行指令:',data)cmd_res = os.popen(data.decode()).read() #接受字符串,执行结果也是字符串print('before send',len(cmd_res))if len(cmd_res) == 0:cmd_res = 'cmd has no output...'conn.send(str(len(cmd_res.encode())).encode('utf-8'))    #先发大小给客户端#time.sleep(0.5) #因为两条发送命令放一起,有可能发送 粘包,但会影响程序效率client_ack = conn.recv(1024) #wait client to confirm ,用这条指令来代替 sleepprint('ack from client:',client_ack.decode('utf-8'))conn.send(cmd_res.encode('utf-8'))print('send done')server.close()

客户端:

import socketclient = socket.socket()client.connect(('localhost',9999))while True:cmd = input('>>:').strip()if len(cmd) == 0:continueclient.send(cmd.encode('utf-8'))cmd_res_size = client.recv(1024) #接受命令结果的长度,byte类型print('命令结果大小:',cmd_res_size)client.send('准备好接收了,loser可以发了'.encode('utf-8')) #用于客户端的 client_ack接收received_size = 0received_data = b''while received_size < int(cmd_res_size.decode()):data = client.recv(1024)received_size += len(data) #每次收到的数据有可能小于1024,所以要用len#print(data.decode())received_data += dataelse:print('cmd res receive done...',received_size)print(received_data.decode())#print(cmd_res.decode())client.close()

运行效果:
服务端:
在这里插入图片描述
客户端:
在这里插入图片描述

例2:使用 get filename 命令传输文件与文件的 md5 加密信息

服务端:

import socket,os,time,hashlibserver = socket.socket()server.bind(('localhost',9999))server.listen()while True:conn,addr = server.accept()print('new conn',addr)while True:print('等待新指令')data = conn.recv(1024)if not data:print('客户端已断开')breakcmd,filename = data.decode().split() #默认按空格分割print('filename:',filename)if os.path.isfile(filename):m = hashlib.md5()with open(filename,'rb') as f:file_size = os.stat(filename).st_sizeconn.send( str(file_size).encode() ) #send file sizeconn.recv(1024) #wait for ackfor line in f:m.update(line)conn.send(line)print('file md5',m.hexdigest())conn.send(m.hexdigest().encode())print('send done')server.close()

客户端:

import socket,hashlibclient = socket.socket()client.connect(('localhost',9999))while True:cmd = input('>>:').strip()if len(cmd) == 0:continueif cmd.startswith('get'):client.send(cmd.encode())server_response = client.recv(1024)print('server response:',server_response)client.send(b'ready to recv file')file_totle_size = int(server_response.decode())received_size = 0filename = cmd.split()[1]f = open(filename + '.new','wb')m = hashlib.md5()while received_size < file_totle_size:#防止粘包问题if file_totle_size - received_size > 1024:  #要收不止一次size = 1024else:   #最后一次剩多少收多少size = file_totle_size - received_sizedata = client.recv(size)received_size += len(data)m.update(data)f.write(data)#print(file_totle_size,received_size)else:new_file_md5 = m.hexdigest()print('file recv done',received_size,file_totle_size)f.close()server_file_md5 = client.recv(1024)print('server file md5',server_file_md5)print('client file md5',new_file_md5)client.close()

socket 实现多并发通信:

服务端:

import socketserverclass MyTCPHandler(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)self.request.send(self.data.upper())except ConnectionResetError as e:print('err',e)breakif __name__ == '__main__':HOST,PORT = 'localhost',9999server = socketserver.ThreadingTCPServer((HOST,PORT),MyTCPHandler)server.serve_forever()

例:模拟 tcp 实现文件上传功能:
服务端:

import socketserver,json,osclass MyTCPHandler(socketserver.BaseRequestHandler):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 = 0while 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.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)self.request.send(self.data.upper())except ConnectionResetError as e:print('err',e)breakif __name__ == '__main__':HOST,PORT = 'localhost',9999server = socketserver.ThreadingTCPServer((HOST,PORT),MyTCPHandler)server.serve_forever()

客户端:

import socket,os,jsonclass FtpClient(object):def __init__(self):self.client = socket.socket()def help(self):msg = '''lscd../..get filenameput filename'''def connect(self,ip,port):self.client.connect((ip, port))def interactive(self):#self.authenticate() 登陆验证while True:cmd = input('>>:')if len(cmd) == 0:continuecmd_str = cmd.split()[0]if hasattr(self,'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_sizemsg_dic = {
    'action':'put','filename':filename,'size':filesize,'overtiden':True}self.client.send( json.dumps(msg_dic).encode('utf-8') )#防止粘包,等服务器确认server_response = self.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 not exist')def cmd_get(self):passftp = FtpClient()
ftp.connect(('localhost',9999))
ftp.interactive()
  相关解决方案