【python自动化第八篇:网络编程】
一、拾遗
动态导入模块
目的是为了在导入模块的过程中将模块以字符的格式导入。
- #!/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自动化第八篇:网络编程】的更多相关文章
- 【python自动化第十一篇】
[python自动化第十一篇:] 课程简介 gevent协程 select/poll/epoll/异步IO/事件驱动 RabbitMQ队列 上节课回顾 进程: 进程的诞生时为了处理多任务,资源的隔离, ...
- Python全栈【Socket网络编程】
Python全栈[socket网络编程] 本章内容: Socket 基于TCP的套接字 基于UDP的套接字 TCP粘包 SocketServer 模块(ThreadingTCPServer源码剖析) ...
- iOS开发网络篇—网络编程基础
iOS开发网络篇—网络编程基础 一.为什么要学习网络编程 1.简单说明 在移动互联网时代,移动应用的特征有: (1)几乎所有应用都需要用到网络,比如QQ.微博.网易新闻.优酷.百度地图 (2)只有通过 ...
- python基础教程总结13——网络编程,
1.网络设计模块 1.1 socket模块 根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认. 1)服务器监听:是服务器端套接 ...
- 图解Python 【第八篇】:网络编程-进程、线程和协程
本节内容一览图: 本章内容: 同步和异步 线程(线程锁.threading.Event.queue 队列.生产者消费者模型.自定义线程池) 进程(数据共享.进程池) 协程 一.同步和异步 你叫我去吃饭 ...
- 第八篇:python基础_8 面向对象与网络编程
本篇内容 接口与归一化设计 多态与多态性 封装 面向对象高级 异常处理 网络编程 一. 接口与归一化设计 1.定义 (1)归一化让使用者无需关心对象的类是什么,只需要知道这些对象都具备某些功能就可以了 ...
- Python之路(第三十三篇) 网络编程:socketserver深度解析
一.socketserver 模块介绍 socketserver是标准库中的一个高级模块,用于网络客户端与服务器的实现.(version = "0.4") 在python2中写作S ...
- Python之路(第三十篇) 网络编程:socket、tcp/ip协议
一.客户端/服务器架构 1.硬件C/S架构(打印机) 打印机作为一个服务端,电脑连接打印机进行打印 2.软件C/S架构 互联网中处处是C/S架构 如谷歌网站是服务端,你的浏览器是客户端(B/S架构也是 ...
- python 网络篇(网络编程)
一.楔子 你现在已经学会了写python代码,假如你写了两个python文件a.py和b.py,分别去运行,你就会发现,这两个python的文件分别运行的很好.但是如果这两个程序之间想要传递一个数据, ...
随机推荐
- js和Jquery获取选中select值和文本
<body> <select name="PaymentType" style="width:110px" > <option v ...
- Ubuntu之网络配置
一.配置大概分三类:通过配置文件配置.通过命令配置.通过图形化的网络连接菜单配置. 拨号无线等的没条件实验,不涉及. 主要文件:/etc/network/interfaces,这里是IP.网关.掩码等 ...
- Oracle DB优化
http://www.jb51.net/article/77876.htm http://www.jb51.net/article/56881.htm http://danni505.blog.51c ...
- android 监听去电实现ip拨号 广播接收者
利用广播实现ip拨号 布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout x ...
- TC SRM 607 DIV2
求拼接完成后的字符串包含的子回文串的数目,一开始还用暴力去做,想都不用想 肯定超时了. 复习了一下求最长子回文串的算法,发现可以类似解决. 给相邻字符之间添加一个'@'字符,这样所有的回文串都是奇数长 ...
- AVPicture、AVFrame和AVPacket
http://blog.csdn.net/ym012/article/details/6540065 从定义上可知,AVPicture是AVFrame的一个子集,他们都是数据流在编解过程中用来保存数据 ...
- iCloud 包括文稿与数据、日历、提醒事项、 通讯录、备忘录、Safari书签
iCloud 能够为用户在设备间同步数据和在服务器上保存数据.当前 iCloud 包括文稿与数据.日历.提醒事项. 通讯录.备忘录.Safari书签.阅读列表.iCloud Tabs.iBooks书签 ...
- Linux内核中流量控制
linux内核中提供了流量控制的相关处理功能,相关代码在net/sched目录下:而应用层上的控制是通过iproute2软件包中的tc来实现, tc和sched的关系就好象iptables和netfi ...
- 【HDOJ】1540 Tunnel Warfare
还不错的一道线段树区间合并.挺巧妙的用法. /* 1540 */ #include <iostream> #include <string> #include <map& ...
- wzplayer,tlplayer支持ActiveX
wzplayer2 for activeX最新谍报 1.支持wzplayer2所有功能 2.支持本地播放,网络播放,加密流播放. 3.支持变速不变调等等. 联系方式:weinyzhou86@gmail ...