Python网络编程(http协议,IO多路复用、select内核监听)

简介: Python网络编程

HTTP协议:


from socket import *
# 接收请求
# 查看请求
# 返回客户端段请求内容


def handleClient(connfd):
    request = connfd.recv(4096)
    # print("***********")
    # print(request)
    # print("************")
    # 按照行切割请求
    request_lines = request.splitlines()
    for line in request_lines:
        print(line.decode())

    try:
        f = open('index.html')
    except IOError:
        response = "HTTP/1.1 303 Not Found\r\n"
        response += "\r\n"  # 空行
        response += '''
                **************************
                Sorry, not found the page.
                **************************
                '''
    else:
        response = "HTTP/1.1 200  OK\r\n"
        response += '\r\n'
        response += f.read()
    finally:
        # 发送给浏览器
        connfd.send(response.encode())


# 创建套接字,调用handleClient完成功能
def main():
    # 创建tcp套接字
    sockfd = socket()
    sockfd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    sockfd.bind(('0.0.0.0', 8000))
    sockfd.listen()
    while True:
        print("Listen the port 8000...")
        connfd, addr = sockfd.accept()
        # 处理浏览器发来的请求
        handleClient(connfd)
        connfd.close()


if __name__ == "__main__":
    main()

S.splitlines  
拆分文件字符串按行分隔


什么是IO?
  • 分为IO设备和IO接口两个部分
  • Linux系统,I/O操作可以有多种方式
  • 比如DIO(DirectI/O)
  • AIO(AsynchronousI/O异步I/O)
  • Memory-MappedI/O(内存映设I/O)等...
  • 同的I/O方式有不同的实现方式和性能,在不同的应用中可以按情况选择不同的I/O方式。

内存中存在 数据交换的操作 认为是IO操作(输入输出)
例如:
    内存与 磁盘数据交换:文件读写、数据库更新
    内存和 终端数据交换:input、print、sys.stdout、sys.stdin、  sys.stder
    内存和 网络数据交换:网络连接、recv、send、recvfrom

IO秘集程型序:
     程序执行中有 大量的IO操作,而比较少的CPU运算操作
     消耗CPU较少,IO 运行时间长
cpu(计算)密集形程序:
     程序存在大量的CPU运算, IO操作相对 较少
      CPU消耗大

IO分类:
    1. 阻塞IO:
        程序 运行中遇到 IO条件没有达成
或传输情况 较慢的情况下 会出现阻塞状态
  阻塞IO是IO最简单的逻辑情形,也 是默认状态
  阻塞IO是 效率很低的IO状态
阻塞情况:
    1.因为IO条件没有达成
        IO 阻塞函数(input、print、recv、recvfrom)
    2.处理IO耗时较长形参阻塞
        文件读写、网络 数据发送过程

    2. 非阻塞IO:
        在程序运行中 遇到IO操作 不让其产生阻塞
实现手段:
    改变IO事件的 属性,使其 变为非阻塞
    通常会和循环一起使用 进行条件的 循环监控

     3.IO多路复用
        定义:
  通过一个监测,可以 同时监控多个IO事件的行为
  当那个IO可以执行,让这个IO事件发生
  同时监控多个IO事件,当 哪个IO事件准备就绪就执行哪个IO事件
  此时形成多个IO时间都可以操作的现象,不必逐个等待执行
IO准备就绪:
  IO事件即将发生时的临界状态不可逆转
  在程序中存在的IO事件中选择要监测的事件
  创建监测,将监测的IO事件注册
  等待监测的IO 事件发生判断是什么 事件
  处理相应的IO


    事件驱动IO
    异步IO
    ...
 
s.setblocking(False)
    功能:
      将套接字 设置为非阻塞状态
   参数:
      默认为阻塞, 设置为 False为非阻塞状态

超时检测:
    原本 阻塞的IO 设置一个最长阻塞 等待时间
    在 规定时间内如果 达到条件正常执行
    如果时间到仍 未达到条件则结束阻塞
        s.settimeout(sec)
            功能:
                    设置套接字的 超时时间
              参数:
                   时间(


select模块
from select import
select 支持:Windows、Linux、Unix  
poll   支持:Linux、Unix
epoll  支持:Linux、Unix

rs, ws, xs = select(rlist, wlist, xlist[, timeout])
    功能:
      监控IO事件 ,阻塞等待监控的IO事件发生
    参数:
        rlist   列表:
          表示存放我们需要 等待处理的IO
        wlist   列表:
          表示存放我们想要 主动处理的IO
        xlist   列表:
          表示存放 出错希望去处理的IO
        timeout超时检测
    返回值:
      rs  列表:
          准备就绪的IO
      ws  列表:
          准备就绪的IO
      xs  列表
          准备就绪的IO

* 在 处理IO时不要形成死循环会让一个 客户端单独占有服务端

* IO多路复兴形成一种 可以同时处理多个IO的效果效率较高


位运算:
    按照二进制位进行位运算操作
    & 按为与   |  按位或    ^  按位异或

    << 左异    >>右移

   11  1011
   14  1110

   &   1010  有0得0
    |    1111  有1得1
   ^    0101  相同为0不同为1
  
   11 << 2  == 44   右侧补零(乘2乘2次)
   14 >> 2  == 3    挤掉右侧的数字(地板除2除2次)
使用:
    1.在 低层硬件操作寄存器
    2.做 标志位的过滤



poll方法实现IO多路复用:
    1.创建poll对象:
       p = select.poll
   2.注册关注的IO:
        p.register(s, POLLIN | PLLERR)
        不关注:
          p.unregister(s)
       事件类别:
          POLLIN  POLLOUT  POLLERR  POLLHUP   POLLPRI
            rlist           wlist          xlist          断开       紧急处理 
    3.监控IO:
        events = p.poll()
       功能: 监控关注的IO 事件
        返回值:
            返回发生IO 事件
    events是一个列表[(fileno, evnet), (), ()....]
    每个就绪IO 对应一个元组描述符就绪事件
            IO地图{s.fileno():s}
   4.处理IO事件

select IO多路复用服务器端:


from socket import *
from select import select
# 创建套接字
s = socket()
# 设置端口重用
s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# 绑定地址
s.bind(('0.0.0.0', 8888))
# 设置队列
s.listen(5)
# 注册监听套接字
rlist = [s]
wlist = []
xlist = [s]

while True:
    print("等待IO发生")
    rs, ws, xs = select(rlist, wlist, xlist)
    # 循环遍历rs准备就绪列表
    for r in rs:
        # 如果有新的客户端链接请求
        if r is s:
            # 链接客户端并返回客户端套接字
            connfd, addr = r.accept()  # r==s 原套接字
            print("Connect from", addr)
            # 将绑定客户端套接字加入监听列表
            rlist.append(connfd)
        # 表示客户端连接套接字准备就绪
        else:
            # 如果是客户端套接字发送数据 则接收
            data = r.recv(1024)
            if not data:  # 如果客户端断开链接
                # 从关注列表移除connfd
                rlist.remove(r)
                r.close()  # 关闭套接字
            else:
                print("Receive:", data.decode())
                # 讲客户端套接字放入wlist
                wlist.append(r)
                # wlist列表会直接返回
    # 循环遍历ws准备就绪列表
    for w in ws:
        # 消息回复
        w.send("这是一条回复消息".encode())
        # 删除并取消监听已处理消息
        wlist.remove(w)
    # xs列表:待处理异常
    for x in xs:
        if x is s:
            s.close()






sys.stdin






客户端:


from socket import *

#  创建套接字
sockfd = socket()

#  发起连接
sockfd.connect(('127.0.0.1', 8888))

while True:
    #  消息收发
    msg = input("Msg>>")
    if not msg:
        break
    sockfd.sendall(msg.encode())
    data = sockfd.recv(1024)
    print(data.decode())

sockfd.close()


应用 :
select服务端,同时关注客户端连接
客户端发送和终端输入。将客户端发送和终端输入的内容全都写入到一个文件中


# myserver.py
# 应用 :
# select服务端,同时关注客户端连接
# 客户端发送和终端输入。将客户端发送和终端输入的内容全都写入到一个文件中

from socket import *
from select import *
from sys import stdin

sock = socket()
sock.getsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sock.bind(("127.0.0.1", 6666))
sock.listen(5)
rlist = [sock, stdin]
wlist = []
xlist = []
file = open("selectdemo.txt", "w+b")
while True:
    rs, ws, xs, = select(rlist, wlist, xlist)
    for r in rs:
        if r == sock:
            connfd, addr = r.accept()
            print("已连接......")
            rlist.append(connfd)
        elif r == stdin:
            data = stdin.readline()
            file.write(data.encode())
            file.flush()
        else:
            data = r.recv(4096)
            if not data:
                rlist.remove(r)
                r.close()
            else:
                file.write(data + "\n".encode())
                file.flush()
                print("已经接收内容并写如select>>>.txt文件内\n 内容:", data.decode())
                r.send("接收成功!".encode())
file.close()


from socket import *

#  创建套接字
sockfd = socket()

#  发起连接
sockfd.connect(('127.0.0.1', 6666))

while True:
    #  消息收发
    msg = input("Msg>>")
    if not msg:
        break
    sockfd.sendall(msg.encode())
    data = sockfd.recv(1024)
    print(data.decode())

sockfd.close()







相关文章
|
12天前
|
搜索推荐 程序员 调度
精通Python异步编程:利用Asyncio与Aiohttp构建高效网络应用
【10月更文挑战第5天】随着互联网技术的快速发展,用户对于网络应用的响应速度和服务质量提出了越来越高的要求。为了构建能够处理高并发请求、提供快速响应时间的应用程序,开发者们需要掌握高效的编程技术和框架。在Python语言中,`asyncio` 和 `aiohttp` 是两个非常强大的库,它们可以帮助我们编写出既简洁又高效的异步网络应用。
61 1
|
13天前
|
网络协议 安全 Linux
Linux C/C++之IO多路复用(select)
这篇文章主要介绍了TCP的三次握手和四次挥手过程,TCP与UDP的区别,以及如何使用select函数实现IO多路复用,包括服务器监听多个客户端连接和简单聊天室场景的应用示例。
57 0
|
13天前
|
存储 Linux C语言
Linux C/C++之IO多路复用(aio)
这篇文章介绍了Linux中IO多路复用技术epoll和异步IO技术aio的区别、执行过程、编程模型以及具体的编程实现方式。
48 1
Linux C/C++之IO多路复用(aio)
|
22天前
|
数据采集 存储 JavaScript
构建你的第一个Python网络爬虫
【9月更文挑战第34天】在数字信息泛滥的时代,快速有效地获取和处理数据成为一项重要技能。本文将引导读者通过Python编写一个简易的网络爬虫,实现自动化地从网页上抓取数据。我们将一步步走过代码的编写过程,并探讨如何避免常见陷阱。无论你是编程新手还是想扩展你的技术工具箱,这篇文章都将为你提供有价值的指导。
68 18
|
3天前
|
消息中间件 监控 网络协议
Python中的Socket魔法:如何利用socket模块构建强大的网络通信
本文介绍了Python的`socket`模块,讲解了其基本概念、语法和使用方法。通过简单的TCP服务器和客户端示例,展示了如何创建、绑定、监听、接受连接及发送/接收数据。进一步探讨了多用户聊天室的实现,并介绍了非阻塞IO和多路复用技术以提高并发处理能力。最后,讨论了`socket`模块在现代网络编程中的应用及其与其他通信方式的关系。
|
8天前
|
机器学习/深度学习 人工智能 算法
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集('矮花叶病', '健康', '灰斑病一般', '灰斑病严重', '锈病一般', '锈病严重', '叶斑病一般', '叶斑病严重'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。再使用Django搭建Web网页操作平台,实现用户上传一张玉米病害图片识别其名称。
22 0
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
|
14天前
|
运维 监控 网络安全
Python 在网络运维方面的自动化应用实例
Python 在网络运维方面的自动化应用实例
39 4
|
13天前
|
Linux C++
Linux C/C++之IO多路复用(poll,epoll)
这篇文章详细介绍了Linux下C/C++编程中IO多路复用的两种机制:poll和epoll,包括它们的比较、编程模型、函数原型以及如何使用这些机制实现服务器端和客户端之间的多个连接。
15 0
Linux C/C++之IO多路复用(poll,epoll)
|
16天前
|
Java Linux
【网络】高并发场景处理:线程池和IO多路复用
【网络】高并发场景处理:线程池和IO多路复用
33 2
|
18天前
|
监控 网络协议 Java
IO 多路复用? 什么是 IO 多路复用? 简单示例(日常生活)来解释 IO 多路复用 一看就懂! 大白话,可爱式(傻瓜式)教学! 保你懂!
本文通过日常生活中的简单示例解释了IO多路复用的概念,即一个线程通过监控多个socket来处理多个客户端请求,提高了效率,同时介绍了Linux系统中的select、poll和epoll三种IO多路复用的API。
44 2

热门文章

最新文章