Python基于scoket实现多路复用TCP局域网文件传输

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

注意事项

  1. msg,read_bool = open_file("vmware.exe")
    是作者电脑中包含的文件,当使用TCP传输时,要记得将这个地方换成电脑中的可读取文件,不然程序会报错
  2. server_ip = "192.168.75.1"
    这里要转换为服务器的ipv4地址
  3. 要先打开server.py文件,再打开client.py。最好是在命令行运行

运行效果

在这里插入图片描述
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容