进击的Python【第八章】:动态导入模块、断言、socket开发之SSH,FTP
一、动态导入模块
知道一个模块名的字符串形式,通过字符串来导入模块
mod = __import__("lib.aa")
print(mod) instance = getattr(mod.aa, "C") obj = instance()
print(obj.name)
__import__("lib.aa")看起来是导入了lib.aa,实际上只导入了lib
下面是官方建议的用法
import importlib
importlib.import_module("lib.aa") #这里就直接导入了lib.aa
二、断言
import importlib
importlib.import_module("lib.aa") obj = aa.C() assert type(obj.name) is str #assert就是断言
print("dddd")
上面表示我断定obj.name就是str,如果正确程序往下走,如果错误直接报错AssertionError
三、通过socket实现SSH功能
server端:
import socket ,os,time
server = 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("客户端已断开")
break
print("执行指令:",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) #lowb防粘包
client_ack = conn.recv(1024) #等待客户端应答,高端防粘包
conn.send(cmd_res.encode("utf-8"))
print("send done")
os.path.isfile()
os.stat("sock")
server.close()
client端:
import socket
client = socket.socket() client.connect(('localhost',9999)) while True:
cmd = input(">>:").strip()
if len(cmd) == 0: continue
client.send(cmd.encode("utf-8"))
cmd_res_size = client.recv(1024) ##接受命令结果的长度
print("命令结果大小:",cmd_res_size)
client.send("准备好接受".encode("utf-8")) #防粘包
received_size = 0
received_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 += data
else:
print("cmd res receive done...",received_size)
print(received_data.decode()) client.close()
四、通过socket实现FTP功能
client端:
import socket
import hashlib client = socket.socket() client.connect(('localhost', 9999)) while True:
cmd = input(">>:").strip()
if len(cmd) == 0: continue
if cmd.startswith("get"):
client.send(cmd.encode())
server_response = client.recv(1024)
print("servr response:", server_response)
client.send(b"ready to recv file")
file_total_size = int(server_response.decode())
received_size = 0
filename = cmd.split()[1]
f = open(filename + ".new", "wb")
m = hashlib.md5() while received_size < file_total_size:
if file_total_size - received_size > 1024: # 要收不止一次
size = 1024
else: # 最后一次了,剩多少收多少
size = file_total_size - received_size
print("last receive:", size) data = client.recv(size)
received_size += len(data)
m.update(data) # 记录MD5
f.write(data)
# print(file_total_size,received_size)
else:
new_file_md5 = m.hexdigest()
print("file recv done", received_size, file_total_size)
f.close()
server_file_md5 = client.recv(1024)
print("server file md5:", server_file_md5) # 输出服务端文件MD5
print("client file md5:", new_file_md5) # 输出传过来的文件的MD5 client.close()
server端:
import hashlib
import socket ,os,time
server = socket.socket()
server.bind(('0.0.0.0',9999) )
server.listen()
while True:
conn, addr = server.accept()
print("new conn:",addr)
while True:
print("等待新指令")
data = conn.recv(1024)
if not 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() ) #send file size
conn.recv(1024) #wait for ack
for line in f:
m.update(line)
conn.send(line)
print("file md5", m.hexdigest())
f.close()
conn.send(m.hexdigest().encode()) #send md5
print("send done") server.close()
五、通过SocketServer实现多并发
The socketserver
module simplifies the task of writing network servers.
There are four basic concrete server classes:
class socketserver.TCPServer(server_address, RequestHandlerClass, bind_and_activate=True)
This uses the Internet TCP protocol, which provides for continuous streams of data between the client and server. If bind_and_activate is true, the constructor automatically attempts to invoke server_bind()
andserver_activate()
. The other parameters are passed to the BaseServer
base class.
class socketserver.UDPServer(server_address, RequestHandlerClass, bind_and_activate=True)
This uses datagrams, which are discrete packets of information that may arrive out of order or be lost while in transit. The parameters are the same as for TCPServer
.
class socketserver.UnixStreamServer(server_address, RequestHandlerClass, bind_and_activate=True)
class socketserver.UnixDatagramServer(server_address, RequestHandlerClass,bind_and_activate=True)
-
These more infrequently used classes are similar to the TCP and UDP classes, but use Unix domain sockets; they’re not available on non-Unix platforms. The parameters are the same as for
TCPServer
.
These four classes process requests synchronously; each request must be completed before the next request can be started. This isn’t suitable if each request takes a long time to complete, because it requires a lot of computation, or because it returns a lot of data which the client is slow to process. The solution is to create a separate process or thread to handle each request; the ForkingMixIn
and ThreadingMixIn
mix-in classes can be used to support asynchronous behaviour.
There are five classes in an inheritance diagram, four of which represent synchronous servers of four types:
+------------+
| BaseServer |
+------------+
|
v
+-----------+ +------------------+
| TCPServer |------->| UnixStreamServer |
+-----------+ +------------------+
|
v
+-----------+ +--------------------+
| UDPServer |------->| UnixDatagramServer |
+-----------+ +--------------------+
创建一个socketserver 至少分以下几步:
- First, you must create a request handler class by subclassing the
BaseRequestHandler
class and overriding itshandle()
method; this method will process incoming requests. - Second, you must instantiate one of the server classes, passing it the server’s address and the request handler class.
- Then call the
handle_request()
orserve_forever()
method of the server object to process one or many requests. - Finally, call
server_close()
to close the socket.
基本的socketserver代码
import socketserver class MyTCPHandler(socketserver.BaseRequestHandler):
"""
The request handler class for our server. It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
""" def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper()) if __name__ == "__main__":
HOST, PORT = "localhost", 9999 # Create the server, binding to localhost on port 9999
server = socketserver.TCPServer((HOST, PORT), MyTCPHandler) # Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()
上面的代码虽然使用了socketserver,但是依然不能实现多并发,我们要想实现多并发通信,需要用到下面这些多并发类
class socketserver.
ForkingTCPServer
class socketserver.
ForkingUDPServer
class socketserver.
ThreadingTCPServer
class socketserver.
ThreadingUDPServer
我们只需要把上面的代码中的
server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
替换为:
server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
就可以实现多线程多并发了
下面我们举个栗子:
import socketserver class 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)
break
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
# Create the server, binding to localhost on port 9999
server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()
进击的Python【第八章】:动态导入模块、断言、socket开发之SSH,FTP的更多相关文章
- python学习之-- 动态导入模块
python 动态导入模块方法1: __import__ 说明: 1. 函数功能用于动态的导入模块,主要用于反射或者延迟加载模块. 2. __import__(module)相当于import mod ...
- python网络编程-动态导入和断言
一:动态导入importlib 在程序运行的过程中,根据变量或者配置动态的决定导入哪个模块,可以使用模块importlib importlib使用示例 二:断言assert 如果接下来的程序依赖于前面 ...
- Python 动态导入模块
动态导入模块 目录结构: zhangsandeMacBook-Air:1110 zhangsan$ tree . . ├── lib │ └── aa.py ├── test1.py lib目录下 ...
- Python importlib(动态导入模块)
使用 Python importlib(动态导入模块) 可以将字符串型的模块名导入 示例: import importlib module = 'module name' # 字符串型模块名 test ...
- python 反射 动态导入模块 类attr属性
1.反射 hasattr getattr delattr setattr 优点:事先定义好接口,接口只有在被完成后才能真正执行,这实现了即插即用,这其实是一种“后期绑定”,即先定义好接口, 然后是再去 ...
- python动态导入模块——importlib
当在写代码时,我们希望能够根据传入的选项设置,如args.model来确定要导入使用的是哪个model.py文件,而不是一股脑地导入 这种时候就需要用上python的动态导入模块 比如此时文件结构为: ...
- python中schedule模块的简单使用 || importlib.import_module动态导入模块
1 import schedule 2 import time 3 4 def start(): #定义一个函数 5 print("****") 6 7 8 if __name__ ...
- Python 实现接口类的两种方式+邮件提醒+动态导入模块+反射(参考Django中间件源码)
实现接口类的两种方式 方式一 from abc import ABCMeta from abc import abstractmethod class BaseMessage(metaclass=AB ...
- Python 实现抽象类的两种方式+邮件提醒+动态导入模块+反射(参考Django中间件源码)
实现抽象类的两种方式 方式一 from abc import ABCMeta from abc import abstractmethod class BaseMessage(metaclass=AB ...
随机推荐
- NodeJS+MongoDB+AngularJS+Bootstrap书店示例
目录 一.Bootstrap 1.1.添加引用 1.2.在页面中使用BootStrap 1.3.可视化布局 二.使用MongoDB创建数据库 2.1.启动MongoDB数据库 2.2.启动数据库GUI ...
- idea、jdk、eclispe中空main方法的线程数量不一样,why?
測试代码: public class Test { public static void main(String[] args) { System.out.println(Th ...
- SeaGlass:手工搭建伪基站监控系统
“伪基站”即假基站,设备一般由主机和笔记本电脑或手机组成,通过短信群发器.短信发信机等相关设备能够搜取以其为中心.一定半径范围内的手机卡信息,利用2G移动通信的缺陷,通过伪装成运营商的基站,冒用他人手 ...
- 【Todo】开个文章学VUE咯
2017年FE架构组制定的框架选型主导为VUE.看了一下VUE的介绍,很不错. 开学~ https://www.zhihu.com/question/38213423 这个里面有VUE应用和背景的一些 ...
- 【深度探索c++对象模型】Function语义学之虚函数
虚函数的一般实现模型:每一个class有一个virtual table,内含该class中的virtual function的地址,然后每个object有一个vptr,指向virtual table. ...
- "undefined reference to strptime"之自己定义strptime函数
简单介绍 strptime()函数可以依照特定时间格式将字符串转换为时间类型.简单点说可以将字符串时间转化为时间戳. 这个函数包括在time.h头文件里,在Unix或者类Unix系统中,我们会常常 ...
- [转]JavaEE开发基础
JavaEE开发基础 1 JavaEE简介 Java平台有三个版本,分别是JavaSE(Java Platform, Standard Edition),JavaEE(Java Platform, E ...
- 【JS】JavaScript引擎的内部执行机制
近期在复习JavaScript,看到setTimeout函数时.想起曾经刚学时,在一本书上看过setTimeout()里的回调函数执行的间隔时间有昌不是后面设置的值.曾经没想太多.网上看了JS大 ...
- 一起talk C栗子吧(第一百二十四回:C语言实例--内置宏)
各位看官们,大家好,上一回中咱们说的是显示变量和函数地址的样例,这一回咱们说的样例是:内置宏.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,我们在编译程序的时候,假设有语法错误,编译器就 ...
- hdu1576 mod 运算的逆元
Problem Description 要求(A/B)%9973,但因为A非常大,我们仅仅给出n(n=A%9973)(我们给定的A必能被B整除.且gcd(B,9973) = 1). Input 数 ...