人生苦短,我用python-- Day8
目录
动态导入模块
断言
socket高级编程
socketServer
动态导入模块 #
先看一下目录结构
动态导入模块有两种方式,我们先来看第一种:
# Author:Sean sir
# 这种情况下导入的是lib目录,如果想调用lib目录下的aa模块,需要在继续往下调用
mod = __import__('lib.aa') obj = mod.aa.C() print(obj.name)
我们来看第二种方法:
# Author:Sean sir
# 这种情况下导入的直接是aa模块,如果想用aa模块里面的方法,直接调用就可以了。
import importlib mod = importlib.import_module('lib.aa') obj = mod.C() print(obj.name)
断言 #
关键字:assert
作用:提高逼格,在操作后面代码前先进行判断。与if进行判断相差无几
代码:
# Author:Sean sir user_input = input('>>>:') assert type(user_input) is str print('aaa') # 输出 >>>:asdf aaa
socket高级编程 #
写一个ssh的工具

# Author:Sean import socket,os server = socket.socket() server.bind(('127.0.0.1',8888)) server.listen() while True: print('我要开始等电话了') conn,add = server.accept() while True: print('电话来了') data = conn.recv(1024) if not len(data):break data = data.decode('utf-8') print(type(data)) cmd_str = os.popen(data).read() len_cmd_str = str(len(cmd_str)).encode('utf-8') conn.send(len_cmd_str) conn.send(cmd_str.encode('utf-8')) server.close()

# Author:Sean sir import socket client = socket.socket() client.connect(('127.0.0.1',8888)) while True: user_input = input('>>:').strip() if not len(user_input): continue client.send(user_input.encode('utf-8')) data_1 = int(client.recv(1024).decode('utf-8')) recv_size = 0 recv = b'' while recv_size != data_1: recv_data = client.recv(1024) recv_size += len(recv_data) recv += recv_data else: print(recv.decode('utf-8')) print('收取执行命令结果完成!') client.close()
上面的server如果两条send命令在一起,那么会出现粘包的问题,粘包:就是说系统会把两个包同时当做一个包的数据发送过去,解决上述问题,继续看代码:
其实很简单,只需要在两个send中间加一个sleep时间就可以了。

# Author:Sean import socket,os,time server = socket.socket() server.bind(('127.0.0.1',8888)) server.listen() while True: print('我要开始等电话了') conn,add = server.accept() while True: print('电话来了') data = conn.recv(1024) if not len(data):break data = data.decode('utf-8') print(data) cmd_str = os.popen(data).read() len_cmd_str = str(len(cmd_str)).encode('utf-8') conn.send(len_cmd_str) time.sleep(0.5) conn.send(cmd_str.encode('utf-8')) server.close()

# Author:Sean sir import socket client = socket.socket() client.connect(('127.0.0.1',8888)) while True: user_input = input('>>:').strip() if not len(user_input): continue client.send(user_input.encode('utf-8')) data_1 = int(client.recv(1024).decode('utf-8')) recv_size = 0 recv = b'' while recv_size != data_1: recv_data = client.recv(1024).decode('utf-8') recv_size += len(recv_data) # recv += recv_data print(recv_data) else: print(recv.decode('utf-8')) print('收取执行命令结果完成!') client.close()
上面的实现形式有没有感觉到low啊,不能时时的返回数据,我们来一个高大上的解决办法
解决思路大概是: 当我发送了执行结果大小后,然后在接受一个客户端发送过来的确认包,如果接受到了,那么继续发送执行结果,如果没有接收到那么就等待,
这里就不会出现粘包的问题了。

# Author:Sean import socket,os,time server = socket.socket() server.bind(('127.0.0.1',7777)) server.listen() while True: print('我要开始等电话了') conn,add = server.accept() while True: print('电话来了') data = conn.recv(1024) if not len(data):break data = data.decode('utf-8') print(data) cmd_str = os.popen(data).read() len_cmd_str = str(len(cmd_str)).encode('utf-8') conn.send(len_cmd_str) #time.sleep(0.5) ack = conn.recv(1024) print(ack) conn.send(cmd_str.encode('utf-8')) server.close()

# Author:Sean sir import socket client = socket.socket() client.connect(('127.0.0.1',7777)) while True: user_input = input('>>:').strip() if not len(user_input): continue client.send(user_input.encode('utf-8')) data_1 = int(client.recv(1024).decode('utf-8')) client.send('我已经做好接受命令准备了!loser发送命令吧!'.encode('utf-8')) recv_size = 0 recv = b'' while recv_size != data_1: recv_data = client.recv(1024).decode('utf-8') recv_size += len(recv_data) # recv += recv_data print(recv_data) else: print(recv.decode('utf-8')) print('收取执行命令结果完成!') client.close()
写一个ftp的工具

# Author:Sean import socket,os,hashlib server = socket.socket() server.bind(('127.0.0.1',7777)) server.listen() while True: print('等待新的客户端连接') conn,add = server.accept() while True: print('等待新指令:') data = conn.recv(1024) if not len(data): print('客户端已断开。。。。。') break cmd,filename = data.decode().split() # print(filename) if os.path.isfile(filename): f = open(filename,'rb') m = hashlib.md5() file_size = os.stat(filename).st_size conn.send(str(file_size).encode()) # 发送一个文件大小到客户端 # print(str(file_size)) ack_info = conn.recv(1024) # 等待客户端发送收到确认信息 for line in f: conn.send(line) f.close() server.close()

# Author:Sean sir import socket client = socket.socket() client.connect(('127.0.0.1',7777)) while True: user_input = input('>>:').strip() if not len(user_input):continue if user_input.startswith('get'): client.send(user_input.encode()) server_response = client.recv(1024) print('Server response:',server_response) client.send(b'ready to recv file!') file_total_size = int(server_response.decode()) received_size = 0 filename = user_input.split()[1] f = open(filename+'_new','wb') while received_size < file_total_size: data = client.recv(1024) received_size += len(data) f.write(data) print(received_size,file_total_size) else: print('file recv done') f.close() client.close()
优化上面的ftp,给上面的ftp传输后的文件md5下,查看下两个文件md5是否一致,最后发送md5的时候,可能会出现粘包的问题,在客户端我们稍微做了处理,当接受的剩余文件小于1024时候的,最后只收文件总大小减去接受到的文件大小的字节数。

# Author:Sean import socket,os,hashlib server = socket.socket() server.bind(('127.0.0.1',7777)) server.listen() while True: print('等待新的客户端连接') conn,add = server.accept() while True: print('等待新指令:') data = conn.recv(1024) if not len(data): print('客户端已断开。。。。。') break cmd,filename = data.decode().split() # print(filename) if os.path.isfile(filename): f = open(filename,'rb') m = hashlib.md5() file_size = os.stat(filename).st_size conn.send(str(file_size).encode()) # 发送一个文件大小到客户端 # print(str(file_size)) ack_info = conn.recv(1024) # 等待客户端发送收到确认信息 for line in f: m.update(line) # 哈希这一行文件 conn.send(line) f.close() conn.send(m.hexdigest().encode()) server.close()

# Author:Sean sir import socket,hashlib client = socket.socket() client.connect(('127.0.0.1',7777)) while True: user_input = input('>>:').strip() if not len(user_input):continue if user_input.startswith('get'): client.send(user_input.encode()) server_response = client.recv(1024) print('Server response:',server_response.decode()) client.send(b'ready to recv file!') file_total_size = int(server_response.decode()) received_size = 0 filename = user_input.split()[1] f = open(filename+'_new','wb') m = hashlib.md5() while received_size < file_total_size: if file_total_size - received_size < 1024: size = file_total_size - received_size else: size = 1024 data = client.recv(size) m.update(data) received_size += len(data) f.write(data) else: print('文件接收完毕!') f.close() server_file_md5 = client.recv(1024) if server_file_md5.decode() == m.hexdigest(): print('经过md5检验,两个文件完全相同!') client.close()
SocketServer #
不同于Socket的是,这个可以处理多个请求,socket只能处理单线程。
创建一个SocketServer大概分如下几步:
第一步:创建一个一个请求处理类,并且这个类要集成BaseRequestHandler,并且还要重写父类的handle()方法。
第二步:你必须实例化一个类,我们常用(TCPServer),并且传递server IP和你上面穿件的请求处理类给这个TCPServer
第三步:可以是用handle_request()或server_forever()进行处理请求,前者只处理一个请求,后者可以处理多个请求,永久执行
第四步:调用server_close()关闭socket
使用socketServer来简单实现以下socket编程,客户端输入数据,返回大写

# Author:Sean sir import socketserver class MyTCPHandler(socketserver.BaseRequestHandler): def handle(self): while True: self.data = self.request.recv(1024).strip() if not self.data : print('主机断开!') break print("{} wrote:".format(self.client_address[0])) print(self.data) self.request.sendall(self.data.upper()) if __name__ == "__main__": HOST, PORT = '127.0.0.1', 8888 server = socketserver.TCPServer((HOST, PORT), MyTCPHandler) server.serve_forever()

# Author:Sean sir import socket client = socket.socket() client.connect(('127.0.0.1',8888)) while True: user_input = input('>>:').strip() if not len(user_input): continue client.send(user_input.encode('utf-8')) data = client.recv(1024) print(data.decode('utf-8')) client.close()
调皮的大王说,现在这种情况,依旧不能实现多线程,那就继续往下看,到底实现多线程!
我们只需要把
server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
换成
server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
就可以了,就是这么简单,我也惊呆了!!!!
0
作者:屌丝逆袭记
出处:https://www.cnblogs.com/xinzhiyu/p/5861229.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律