一、拾遗

动态导入模块

  目的是为了在导入模块的过程中将模块以字符的格式导入。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:wanghui
lib = __import__("lib.aa") #传统方法
lib.aa import importlib
aa = importlib.import_module("lib.aa") #官方做法
print(aa.C().name)

断言

  类似于if,实际的意思就是如多对应的条件为真就执行,不为真就报错。

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端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:wanghui
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端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:wanghui
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 -*-
#Author:wanghui
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() #关闭连接

server:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:wanghui
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: #如果客户端断开,那么就退出此次接收,重新回到监听状态
print("客户端已经断开!")
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(str(len(cmd_res.encode())).encode('utf-8')) #先发大小给客户端
conn.send(cmd_res.encode('utf-8')) #向客户端发送数据,必须是bytes
print("发送完成!")
server.close() #断开连接

  3.粘包问题

    server连续调用send的时候缓冲区会将挨着的两次操作发给客户端,导致两次send的内容都同时发给了客户端,所以其中的一个方法就是在服务器端的send之间加入sleep时间,可以解决这个问题

server:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:wanghui
import socket,os,time 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: #如果客户端断开,那么就退出此次接收,重新回到监听状态
print("客户端已经断开!")
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(str(len(cmd_res.encode())).encode('utf-8')) #先发大小给客户端
#time.sleep(0.5) #防止粘包的一种方法
client_ack= conn.recv(1024) #等待确认
print('ack from client:',client_ack)
conn.send(cmd_res.encode('utf-8')) #向客户端发送数据,必须是bytes
print("发送完成!")
server.close() #断开连接

  client:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:wanghui
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) #打印接收大小
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判断
received_data += data #每次读取进来的data写入received_data
# print(data.decode())
else:
print("cmd rees received done",received_size)
print(received_data.decode())
client.close() #关闭连接

  4.简易的文件传输案例

    server端的设计:

      • 读取文件名
      • 检测文件是否存在
      • 打开文件
      • 检测文件大小
      • 发送文件大小和MD5值给客户端
      • 等待客户端确认
      • 开始边读取边发数据    
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:wanghui
import socket,os,time,hashlib 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: #如果客户端断开,那么就退出此次接收,重新回到监听状态
print("客户端已经断开!")
break
cmd,filename = data.decode().split() #分割命令和文件名称
print(filename) #打印文件名
if os.path.isfile(filename): #判断是否为文件
f = open(filename,'rb') #打开文件
m = hashlib.md5() #定义MD5加密方式
file_size = os.stat(filename).st_size #确定文件大小
conn.send(str(file_size).encode()) #发送文件大小
conn.recv(1024) #等待确认
for line in f: #读取文件
m.update(line) #边读取边加密
conn.send(line) #边发送文件
print('file md5',m.hexdigest()) #打印文件的MD5
f.close() #关闭文件
conn.send(m.hexdigest().encode()) #发送MD5
print("发送完成!!") server.close()

  client端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:wanghui
import socket,os,hashlib client = socket.socket() #实例化socket
client.connect(("localhost",9999)) #开始连接啦 while True: #发送数据啦
cmd = input(">>:").strip()
if len(cmd) == 0:continue #如果长度为0,就继续返回循环
if cmd.startwith('get'): #定义开始
client.send(cmd.encode()) #客户端发送命令
server_resbonce = client.recv(1024) #接收服务器端数据
print("server resbonce:",server_resbonce)
client.send("准备接收文件".encode())
file_total_size = int(server_resbonce.decode()) #定义接受的文件总大小
received_size=0 #初始接收文件
filename = cmd.split()[1] #获取文件名
f = open(filename + '.new','wb') #开始写文件
m = hashlib.md5() #定义MD5加密 while received_size < file_total_size: #如果接收的文件小于总文件大小,就执行如下
data = client.recv(1024) #定义接收文件
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_total_size,received_size)
f.close() #关闭文件
server_md5 = client.recv(1024) #接收服务器端MD5
print(server_md5,new_file_md5) #对比MD5 client.close()

  

【python自动化第八篇:网络编程】的更多相关文章

  1. 【python自动化第十一篇】

    [python自动化第十一篇:] 课程简介 gevent协程 select/poll/epoll/异步IO/事件驱动 RabbitMQ队列 上节课回顾 进程: 进程的诞生时为了处理多任务,资源的隔离, ...

  2. Python全栈【Socket网络编程】

    Python全栈[socket网络编程] 本章内容: Socket 基于TCP的套接字 基于UDP的套接字 TCP粘包 SocketServer 模块(ThreadingTCPServer源码剖析) ...

  3. iOS开发网络篇—网络编程基础

    iOS开发网络篇—网络编程基础 一.为什么要学习网络编程 1.简单说明 在移动互联网时代,移动应用的特征有: (1)几乎所有应用都需要用到网络,比如QQ.微博.网易新闻.优酷.百度地图 (2)只有通过 ...

  4. python基础教程总结13——网络编程,

    1.网络设计模块 1.1 socket模块    根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认. 1)服务器监听:是服务器端套接 ...

  5. 图解Python 【第八篇】:网络编程-进程、线程和协程

    本节内容一览图: 本章内容: 同步和异步 线程(线程锁.threading.Event.queue 队列.生产者消费者模型.自定义线程池) 进程(数据共享.进程池) 协程 一.同步和异步 你叫我去吃饭 ...

  6. 第八篇:python基础_8 面向对象与网络编程

    本篇内容 接口与归一化设计 多态与多态性 封装 面向对象高级 异常处理 网络编程 一. 接口与归一化设计 1.定义 (1)归一化让使用者无需关心对象的类是什么,只需要知道这些对象都具备某些功能就可以了 ...

  7. Python之路(第三十三篇) 网络编程:socketserver深度解析

    一.socketserver 模块介绍 socketserver是标准库中的一个高级模块,用于网络客户端与服务器的实现.(version = "0.4") 在python2中写作S ...

  8. Python之路(第三十篇) 网络编程:socket、tcp/ip协议

    一.客户端/服务器架构 1.硬件C/S架构(打印机) 打印机作为一个服务端,电脑连接打印机进行打印 2.软件C/S架构 互联网中处处是C/S架构 如谷歌网站是服务端,你的浏览器是客户端(B/S架构也是 ...

  9. python 网络篇(网络编程)

    一.楔子 你现在已经学会了写python代码,假如你写了两个python文件a.py和b.py,分别去运行,你就会发现,这两个python的文件分别运行的很好.但是如果这两个程序之间想要传递一个数据, ...

随机推荐

  1. 学无止境,学习AJAX,跨域(三)

    学习AJAX其实有个很重要的应用,就是为了执行另外几个站点的ASP,返回结果. 真正用起来,发现2个问题,>_> 不许笑,一向做DELPHI,接触ASP不多的我,的确问题大堆. 第一个问题 ...

  2. asp.net中对象的序列化,方便网络传输

    对象序列化 是将对象状态转换为可保持或传输的格式的过程.反序列化 是将流转换为对象序列化和反序列化相结合 可以使对象数据轻松的存储和传递 在 .NET 中,如果是对象可序列化,需要在 声明对象的开始部 ...

  3. 华为机试题——数组排序,且奇数存在奇数位置,偶数存在偶数位置

    题目要求很简单,就是给你一个数组,对它进行排序,并且排序后,奇数要放在奇数的位置上,偶数要放在偶数的位置上,如果不满足这个规则的话就在数组上填充0 实现代码如下,文中值得注意的一点就是如何判读这个数字 ...

  4. Fast CGI 工作原理

    http://www.cppblog.com/woaidongmao/archive/2011/06/21/149092.html 一.FastCGI是什么? FastCGI是语言无关的.可伸缩架构的 ...

  5. Design Tutorial: Inverse the Problem

    Codeforces Round #270 D:http://codeforces.com/contest/472/problem/D 题意:给以一张图,用邻接矩阵表示,现在问你这张图能不能够是一棵树 ...

  6. Ubuntu zookeeper-3.5.0-alpha启动错误 zkEnv.sh: Syntax error: "(" unexpected (expecting "fi")(转)

    昨天小猿我把Ubuntu Server64位上的 zookeeper换成了最新版本的,结果启动的时候出错:之前zookeeper-3.3.6是没有任何问题的,换成了zookeeper3.5出现了下面的 ...

  7. Tomcat 6.0下配置HTTPS

    最近项目需要使用到https,所以回顾整理了一下,其实在tomcat的文档中已经有了详细描述,我们启动Tomcat后,可以在docs文档中找到 地址如下:http://localhost:8080/d ...

  8. grep简单常用的语法介绍

    说明: grep -n 关键字 查询的文档 ->-n表示打印行号 grep -c 关键字 查询的文档1 查询的文档2 ->-c表示输出匹配行的数目,而不是输出匹配的行. grep -rn ...

  9. cat主要有三大功能

    cat主要有三大功能:1.一次显示整个文件.$ cat filename2.从键盘创建一个文件.$ cat > filename     只能创建新文件,不能编辑已有文件.3.将几个文件合并为一 ...

  10. .NET程序内,访问私有或者保护成员的技巧

    如果是C++,我们可以计算对象内成员的位置,然后偏移指针以访问类型的所有非公开成员.但是.NET对象完全受GC管理,地址根本无法得到,并且也无法通过指针调用方法. 当然... 这是一种很不值得推荐的技 ...