局域网传输的基本信息
1.IO是什么?
⦁定义
在内存中存在数据交换的操作
和终端交互:input, output
和磁盘交互:read, write
和网络交互:recv, send
①IO密集型:在程序当中存在大量的IO,而CPU的运算较少,消耗CPU资源小,耗时长,效率不高
②计算密集型:在运算中存在大量计算,IO行为较少,CPU消耗大,执行速度快
⦁ 阻塞IO
定义:在执行IO操作时由于不满足某些条件形成的阻塞形态
效率:阻塞IO是一种效率很低的IO,逻辑简单。
⦁ 非阻塞IO
定义:通过修改IO的属性行为,使原本阻塞的IO变为非阻塞的状态
修改方法:
sockf.setblocking(bool)
功能:设置套接字为非阻塞IO
参数:True为阻塞,False为非阻塞
Sockf.settimeout(sec)
功能:超时检测,阻塞等待的时间,超时后不再阻塞
参数:超时时间,以秒为单位
2.IO多路复用
定义
同时监控多个IO事件,当哪个IO事件准备就绪就执行哪个IO,以此形成可以同时处理多个IO的行为。避免一个IO阻塞造成其他IO无法执行,提高IO执行效率。
具体方案:①select: windows/linux/unix
②poll: linux/unix
③epoll: linux
select具体用法
①导入: from select import select
②监控IO:
rs,ws,xs = select(rlist,wlist,xlist)
功能:监控多个IO事件,阻塞等待IO发生
参数:rlist 列表,关注的等待发生的IO事件
wlist 列表,要主动处理的IO事件
xlist 列表,发生异常时要处理的IO事件
返回值:
rs: 列表,rlist中准别就绪的IO
ws: 列表,wlist中准别就绪的IO
xs: 列表, xlist中准别就绪的IO
③注意:
- wlist 中如果有IO事件,select 会立即返回为ws
*处理事件过程找那个不要出现死循环等长期占有服务端的情况
*IO多路复用消耗资源较少,效率较高 - 套接字获取地址的方法:
sockfd.getpeername() 返回一个元组: (ip,port)
3.实现多路复用局域网文件传输
server.py
from select import *
from socket import *#导入模块
from FileOperation import *
ip_address = "0.0.0.0"#设置IPV4地址
port = 8097#设置端口
num = 3#设置监听数量
addrs = []
server = socket(
family=AF_INET,
type = SOCK_STREAM,
proto = 0
)
server.bind((ip_address,port))
server.setsockopt(SOL_SOCKET,SO_REUSEADDR,True)
#SO_REUSEADDR指的是一个网络地址在短时间重复利用
server.listen(num)
print("server is listening to the port:%d"%port)
print("server can be connected for %d clients at the same time "%num)
print("------------------------------------")
rlist = [server]#存放关注的,等待发生的IO事件
wlist = []#存放主动处理的IO事件
xlist = []#存放发生异常的事件
while True:
rs,ws,xs = select(rlist,wlist,xlist)
for i in rs:#遍历准备就绪的IO事件,如果准备就绪的IO事件i,如果i等于服务器server时,有客户端连接上来了。
if i is server:
coon,addr = i.accept()#连接
rlist.append(coon)
print(addr,"is connected......")
addrs.append(addr)
else:#如果i等于连接套接字类型,那就去接收
data = i.recv(102400)#阻塞等待发送消息
msg = data
add_file("./vmware-1.exe",msg)
if msg == "quit":#客户端要求断开连接
rlist.remove(i)
i.close()
continue
else:
i.send(b"ok")#向客户端反馈OK信息
server.close()
client.py
from socket import *#导入socket库
import time
from FileOperation import *
global server_ip
global server_port
server_ip = "192.168.75.1"#这里使用cmd查看主机ipv4地址
server_port = 8097
client = socket(
family = AF_INET,
type = SOCK_STREAM,
proto = 0)
while True:
try:#服务端未打开时的异常
client.setsockopt(SOL_SOCKET,SO_REUSEADDR,True)
client.connect((server_ip,server_port))
except:
print("您是不是远离服务器了,靠近后再试一试!")
server_ip = input("如果ip接口输入错误,请在这里重试:")
server_port = input("如果ip端口输入错误,请在这里重试:")
print("正在重试中...")
print(server_ip)
print(server_port)
else:
break
while True:
msg,read_bool = open_file("vmware.exe")
client.send(msg)
if msg == "quit":
break
data = client.recv(1024)
msg = data.decode()
print("server:%s"%msg)
client.close()
FileOperation.py
def open_file(dir):
ReadBool = None
msg = None
try:
with open(dir,"rb")as f:
msg = f.read()
except:
pass
else:
ReadBool = True
return msg,ReadBool
def write_file(dir,message):
WriteBool = None
msg = None
try:
with open(dir,"wb+")as f:
f.write(message)
f.close()
except:
pass
else:
WriteBool = True
return msg,WriteBool
def add_file(dir,message):
AddBool = None
msg = None
try:
with open(dir,"ab+")as f:
f.write(message)
f.close()
except:
pass
else:
AddBool = True
return msg,AddBool
注意事项
msg,read_bool = open_file("vmware.exe")
是作者电脑中包含的文件,当使用TCP传输时,要记得将这个地方换成电脑中的可读取文件,不然程序会报错server_ip = "192.168.75.1"
这里要转换为服务器的ipv4地址- 要先打开server.py文件,再打开client.py。最好是在命令行运行