【python自动化第八篇:网络编程】
一、拾遗
动态导入模块
目的是为了在导入模块的过程中将模块以字符的格式导入。
|
1
2
3
4
5
6
7
8
9
|
#!/usr/bin/env python# -*- coding:utf-8 -*- lib = __import__("lib.aa") #传统方法
lib.aa import importlib
aa = importlib.import_module("lib.aa") #官方做法
print(aa.C().name)
|
断言
类似于if,实际的意思就是如多对应的条件为真就执行,不为真就报错。
|
1
2
3
4
5
6
|
assert type(1223) is str
print("this is str")
#等同于if type(1223) is str:
exit("must be int")
print("this is str")
|
二、socket继续
1、浅谈server端的原理:
(1)、申明socket实例 server = socket.socket(AF.INET(地址簇),sock.SOCK_STREAM(代表tcp/ip))
地址簇分类:socket.AF_INET ----> ipv4 , socket.AF_INET6 -------> ipv6 , socket.AF_UNIX --------> 本地通信
协议类型:socket.SOCK_STREAM -----> tcp/ip , socket.SOCK_DGRAM -----> udp
(2)、绑定ip地址和端口 server.bind(("localhost",port))
(3)、开始监听:while True:
conn,addr = server.accept() 阻塞状态
(4)、循环接受信息
while True:
print("new conn",addr) #打印连接的客户端ip
data = conn.recv(1024) #接受数据大小(官方最大建议8192),这边接收数据的时候默认也是阻塞的
if not data: ***如果客户端 已断开的话conn.recv就会接收到空数据
break
conn.send(data.upper()) #发送数据
浅谈客户端的原理:
(1)、实例化一个socket client = socket.socket()
(2)、定义一个 链接的地址和端口 client.connect(("server_ip",port))
(3)、这会儿就可以发数据了 client.send(data)
(4)、接收数据 client.recv()
2、通过socket实现一个简单的ssh协议:
client端:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#!/usr/bin/env python# -*- coding:utf-8 -*- import socket,os
client = socket.socket() #实例化socket
client.connect(("localhost",9999)) #开始连接啦
while True: #发送数据啦
cmd = input("请输入命令>>:").strip()
if len(cmd) == 0:continue #如果长度为0,就继续返回循环
client.send(cmd.encode('utf-8')) #发送命令(byte)
cmd_res = client.recv(1024) #接收返回结果
print(cmd_res.decode()) #打印结果
client.close() #关闭连接
|
server端:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#!/usr/bin/env python# -*- coding:utf-8 -*- import socket,os
server = socket.socket() #申明实例
server.bind(('localhost',9999)) #绑定ip和端口
server.listen() #等待连接
while True:
conn,addr= server.accept() #监听
print("开始连接啦",addr)
while True: #正式接受数据啦
print("开始新连接啦")
data = conn.recv(1024) #定义传输大小
if not data: #如果客户端断开,那么就退出此次接收,重新回到监听状态
break
print("开始 执行客户端命令",data)
cmd_res = os.popen(data.decode()).read() #读取客户端命令(bytes转换成str)
print("接受之前:",len(cmd_res))
if len(cmd_res) == 0:
cmd_res = "cmd has no output ..."
conn.send(cmd_res.encode('utf-8')) #向端发送数据,必须是bytes
print("发送完成!")
server.close() #断开连接
|
上面的基本连接模式会出现客户端发送的指令客户端不能一次性全部返回的问题,这样的话解决方式只能有:超时和确认缓冲区多少次发完的问题
然而多少次将缓冲区的内容发完呢?不晓得。。。所以只能通过在超时问题上做文章了
client:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket,os
client = socket.socket() #实例化socket
client.connect(("localhost",9999)) #开始连接啦
while True: #发送数据啦
cmd = input("请输入命令>>:").strip()
if len(cmd) == 0:continue #如果长度为0,就继续返回循环
client.send(cmd.encode('utf-8')) #发送命令(byte)
cmd_res_size = client.recv(1024) #接受返回数据的大小
print("接受的数据",cmd_res_size) #打印接收大小
received_size = 0
received_data = b''
while received_size < int(cmd_res_size.decode()): #只要不相等就一直收
data = client.recv(1024)
received_size += len(data) #每次接收到的数据有可能小于1024,所以要用len判断
received_data += data #每次读取进来的data写入received_data
# print(data.decode())
else:
print("cmd rees received done",received_size)
print(received_data.decode())
client.close() #关闭连接