• PYTHON2.day04


    day23作业:

      1 from select import select
      2 from socket import *
      3 import sys
      4 from time import ctime
      5 
      6 s = socket()
      7 s.bind(('0.0.0.0',8888))
      8 s.listen(3)
      9 
     10 #监控
     11 rlist = [s,sys.stdin]#标准输入
     12 wlist = []
     13 xlist = []
     14 
     15 #日志文件
     16 f = open('log.txt','a')
     17 
     18 #训话监控
     19 while True:
     20     rs,ws,xs = select(rlist,wlist,xlist)
     21     for r in rs:
     22         if r is s:
     23             c,addr = r.accept()
     24             rlist.append(c)
     25         elif r is sys.stdin:
     26             f.write("%s %s"%(ctime(),r.readline()))#在终端度一行内容并写入
     27             f.flush()#刷新文件缓冲
     28         else:
     29             data = c.recv(1024)
     30             if not data:#如果客户端退出
     31                 rlist.remove()
     32                 r.close()
     33                 continue
     34             f.write("%s %s
    "%(ctime(),data.decode())) #在文件中追加当前时间...
     35 
    select_test.py
      1 from socket import *
      2 
      3 #创套接字
      4 sockfd = socket()
      5 
      6 #发起连接
      7 server_addr = ('172.40.71.149',8888)
      8 sockfd.connect(server_addr)
      9 
     10 #收发消息
     11 while  True:
     12     #发
     13     data = input(">>")
     14     sockfd.send(data.encode())
     15     if not data:
     16         break
     17     #收
     18     # data = sockfd.recv(1024)
     19     # print("From server:",data.decode())
     20 
     21 #关闭套接子
     22 sockfd.close()
     23 
    tcp_clent.py
    2019-02-18_9-45-30



    一.基于poll方法的IO多路复用

    1.select。poll()
       功能:创建poll对象
       返回值:poll
    2.p.register(fd,event)
       功能:注册关注的IO事件
       参数:fd 要关注的IO
            event 要关注的IO事件类型
                 * 常用类型:POLLIN 读IO事件 (rlist)
                             POLLOUT 写IO事件(wlist)
                             POLLERR 异常IO  (xlist)
                             POLLHUP 断开连接
                *e.g.  p.register(sockfd,POLLIN)#关注套接字的读事件
                        p.register(sockfd,POLLIN|POLLERR)#关注套接字的读事件
                        p.register(sockfd)#关注所有事件(尽量不用)

            p.unregister(fd)
             功能:取消对IO的关注
             参数:IO对象或者对象的frieno
            
    *函数可以返回实例化对象

    3.  enents = p.poll()#对象的方法
         功能:阻塞等待监控的IO事件发生
         返回值:返回发生的IO
                 events格式 [(fileno,event),()...]
                 每个元组为一个就绪IO,元组第一项是该IO的fileno,
                 第二项为该IO的就绪的事件类型
                
         * 需要通过fileno寻找对应的IO对象,建立对应字典确保字典中IO和关注的IO时刻保持一致
           字典格式:{fileno:io_obj}
          
    4.poll_server 步骤
       【1】创建套接字
       【2】将套接字register
       【3】创建查找字典,并维护
       【4】循环建监控IO发生
       【5】处理发生的IO
       

      1 from socket import *
      2 from select import *
      3 
      4 #创建要关注的IO
      5 s = socket()
      6 s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
      7 s.bind(('0.0.0.0',8888))
      8 s.listen(5)
      9 
     10 #创建poll对象
     11 p = poll()
     12 
     13 #建立查找字典
     14 fdmap = {s.fileno():s}
     15 
     16 #注册ID
     17 p.register(s,POLLIN|POLLERR)
     18 
     19 
     20 #循环监控
     21 while True:
     22     events = p.poll()#阻塞,返回列表
     23     #遍历列表,处理IO
     24     #元祖:fd文件描述符,event事件
     25     for fd,event in events:
     26 
     27         if fd ==s.fileno():#s就绪(监听套接字准备就绪)
     28             c,addr = fdmap[fd].accept()
     29             print("Connect from",addr)
     30             #添加新的注册ID
     31             p.register(c,POLLIN|POLLHUP)
     32             fdmap[c.fileno()] = c
     33 
     34         elif event & POLLHUP:
     35             print("客户端退出")
     36             p.unregister(fd)#取消关注
     37             fdmap[fd].close()
     38             del fdmap[fd]
     39 
     40         elif event & POLLIN:#真->pollin就绪;假-->poll未就绪
     41             data = fdmap[fd].recv(1024)
     42             print("Receive:",data.decode())
     43             fdmap[fd].send(b'Receive your msg')
     44 
    poll_server.py

      1 from socket import *
      2 
      3 #创套接字
      4 sockfd = socket()
      5 
      6 #发起连接
      7 server_addr = ('172.40.71.149',8888)
      8 sockfd.connect(server_addr)
      9 
     10 #收发消息
     11 while  True:
     12     #发
     13     data = input(">>")
     14     sockfd.send(data.encode())
     15     if not data:
     16         break
     17     #收
     18     data = sockfd.recv(1024)
     19     print("From server:",data.decode())
     20 
     21 #关闭套接子
     22 sockfd.close()
     23 
    tcp_cent.py

    2019-02-18_11-20-30
                
    二.基于epoll方法的IO多路复用
         * 生成对象改为epoll()
         * 生成对象事件类型改为EPOLL类型
        
         epoll特点:
             *epoll 效率比select poll 要高
             *epoll(一直申请) 监控IO数量比select(1024)多
             *epoll的触发方式比poll要多(EPOLLET边缘触发)
          

      1 from socket import *
      2 from select import *
      3 
      4 #创建要关注的IO
      5 s = socket()
      6 s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
      7 s.bind(('0.0.0.0',8888))
      8 s.listen(5)
      9 
     10 #创建poll对象
     11 p = epoll()
     12 
     13 #建立查找字典
     14 fdmap = {s.fileno():s}
     15 
     16 #注册ID
     17 p.register(s,EPOLLIN|EPOLLERR)
     18 
     19 
     20 #循环监控
     21 while True:
     22     events = p.poll()#阻塞,返回列表
     23     #遍历列表,处理IO
     24     #元祖:fd文件描述符,event事件
     25     for fd,event in events:
     26 
     27         if fd ==s.fileno():#s就绪(监听套接字准备就绪)
     28             c,addr = fdmap[fd].accept()
     29             print("Connect from",addr)
     30             #添加新的注册ID
     31             p.register(c,EPOLLIN|EPOLLHUP)
     32             fdmap[c.fileno()] = c
     33 
     34         elif event & EPOLLHUP:
     35             print("客户端退出")
     36             p.unregister(fd)#取消关注
     37             fdmap[fd].close()
     38             del fdmap[fd]
     39 
     40         elif event & EPOLLIN:#真->pollin就绪;假-->poll未就绪
     41             data = fdmap[fd].recv(1024)
     42             print("Receive:",data.decode())
     43             fdmap[fd].send(b'Receive your msg')
     44 
     45 
     46 
    epoll_server.py

      1 from socket import *
      2 
      3 #创套接字
      4 sockfd = socket()
      5 
      6 #发起连接
      7 server_addr = ('172.40.71.149',8888)
      8 sockfd.connect(server_addr)
      9 
     10 #收发消息
     11 while  True:
     12     #发
     13     data = input(">>")
     14     sockfd.send(data.encode())
     15     if not data:
     16         break
     17     #收
     18     data = sockfd.recv(1024)
     19     print("From server:",data.decode())
     20 
     21 #关闭套接子
     22 sockfd.close()
     23 
    tcp_clent.py

    2019-02-18_11-34-14 
    三.struct模块的使用
    1.原理:将一组金丹数据进行打包,转换为bytes格式发送。或者将一组bytes格式数据,进行解析。
    2.接口使用
       [1] Struct(fmt)
           功能:生成结构化对象
           参数:fmt 定制了数据结构
           e.g. 要发送数据 1 b'zhangsan'  1.75
                fmt参数     "i8sf"(8个字串)
      [2]st.pack(v1,v2,v3...)
          功能:将一组数据按照指定格式打包转换为bytes
          参数:要打包的数据
          返回值:bytes字节串
       [3]st.unpack(bytes)
           功能:将bytes字节串按照指定的格式解析
           参数:要解析的字符串
           返回值:解析后的内容
      [4]struct.pack(fmt,v1,v2,v3...)
          struct.unpack(fmt,bytes_data)

          说明:可以使用struct模块直接调用pack unpack
                此时这两个参数传入fmd,其他用发功能相同
       

      1 from socket import *
      2 import struct
      3 
      4 s = socket(AF_INET,SOCK_DGRAM)
      5 s.bind(('0.0.0.0',8888))
      6 
      7 #确定数据结构
      8 st = struct.Struct('i16sf')
      9 
     10 while True:
     11     data,addr = s.recvfrom(1024)
     12     #解析
     13     data = st.unpack(data)
     14     print(data)
     15 
     16 s.close()
    struct_receive.py

      1 from socket import *
      2 import struct
      3 
      4 ADDR = ('172.40.71.149',8888)
      5 s = socket(AF_INET,SOCK_DGRAM)
      6 
      7 while True:
      8     my_id = int(input("id:"))
      9     name = input("name:")
     10     height = float(input("height:"))
     11     # len = len(name)
     12 
     13     fmt = "i16sf"
     14     data = struct.pack(fmt,my_id,name.encode(),height)
     15     s.sendto(data,ADDR)
     16 
     17 s.close()
    struct_clent.py

    stru       
         
    四.本地套接字
         1.功能:用于本地的两个程序之间进行数据的收发
         2.套接字文件:用于本地套接字之间通信时,进行数据传输的介质。
         3.创建本地套接字的流程
           【1】创建本地套接字
                socket = sorted(AF_UNIX,SOCK_STREEAM)
           【2】绑定本地套接字文件
                sockfd.bind(file)
           【3】监听,接收客户端连接,消息收发
                listen()-->accept()-->recv(),send()
         
         cookie:Linux下文件类型
             b(块设备文件)     
             c(字符设备文件)  
             d(目录)
             -(普通文件)    
             l(连接文件)   
             s(套接字文件)       
             p(管道文件)
            

      1 from socket import *
      2 import os
      3 
      4 #确定套接字文件
      5 sock_file = './sock'
      6 
      7 #判断文件是否存在,存在就删除
      8 if os.path.exists(sock_file):
      9     os.remove(sock_file)
     10 
     11 
     12 #创建本地套接字
     13 sockfd = socket(AF_UNIX,SOCK_STREAM)
     14 
     15 #绑定套接字文件
     16 sockfd.bind(sock_file)
     17 
     18 #监听,连接
     19 sockfd.listen(3)
     20 while True:
     21     c,addr = sockfd.accept()
     22     while True:
     23         data = c.recv(1024)
     24         if not data:
     25             break
     26         print(data.decode())
     27     c.close()
     28 sockfd.close()
    unix_receive.py

      1 from socket import *
      2 
      3 #确保两边使用同一个套接字文件
      4 sock_file = './sock'
      5 sockfd = socket(AF_UNIX,SOCK_STREAM)
      6 sockfd.connect(sock_file)
      7 
      8 while True:
      9     msg = input(">>")
     10     if not msg:
     11         break
     12     sockfd.send(msg.encode())
     13 
     14 sockfd.close()
    unix_send.py

    unix
        
    五.多任务编程
         1.意义:充分利用计算机多核咨询,提高程序的运行效率
         2.实现方案:多进程 ,多线程
         3.并行,并发概念
           * 并发:同时处理多个任务,内核咋任务间不断切换达到多个任务被同时执行的效果,
                   实际每个时刻只有一个任务占有内核
           * 并行:多个任务利用计算机多核资源在同时执行,此时多个任务间同时为并行关系。
          
          
    六.进程(process)
        1.定义:程序在计算机中的一次运行
          * 程序是一个可执行的文件是静态的占有磁盘
          * 进程是一个动态的过程描述,占有计算机运行资源,有一定的生命周期
         
        2. 如何产生一个进程
           【1】用户空间通过调用程序接口命令发起请求
           【2】操作系统接收用户请求,开始创建进程
           【3】操作系统调配计算机资源,确定进程状态等
           【4】操作系统将创建的进程提供给用户使用
        3.进程概念
            * cpu时间片:如果一个进程占有cpu内核则称这个进程在cpu时间片上
            *PCB(进程控制块):在内存中开辟的一块空间,用于存放进程的基本信息,
                 也用于系统查找识别进程
            *进程ID(PID):系统为每个进程分配的一个大于0 的整数,作为进程ID,每个ID不会重复。
           
            Linux查看进程ID:ps -aux
            ps-aux
            * 父子进程:系统中每一个进程(除了系统初始化进程)
             都有唯一的父进程,可以有0个或多个子进程。父子进程关系便于进程管理
            
             查看进程树:pstree

    pstree
             *进程状态
                  三态:
                      就绪态:进程具备执行条件。等待分配cup资源
                      运行态:进程占有cpu时间片正在运行
                      等待态:进程暂停时停止运行。
                  五态:
                      新建:创建一个进程,获取资源的过程
                      终止:进程结束,释放资源的过程
                     
                 状态查看命令:ps -aux --->STAT列
                
                 S 等待态
                 R 执行态
                 D 等待态
                 T 等待态
                 Z 僵尸     
          
                 < 有较高优先级
                 N 优先级较低
                 + 前台进程
                 s 会话组组长
                 l 有多线程的
                
                

    面试要求:1.什么是进程,进程和程序有什么区别
               2.进程有哪些状态,状态之间如何转化
              
    作业:1.对要求问题总结回答
           2.整理网络编程重点程序
           能够自己写出 tcp服务器 udp服务端  select服务端  poll服务端

  • 相关阅读:
    几何变换
    图片移动、旋转、resize、
    load、display、save
    java基础—java三大集合ArrayList、HashSet、HashMap
    java基础—修饰符、抽象类、接口
    java基础——转义字符
    java基础—String类型常用api
    Python中 sys.argv[]的用法
    Java—this关键字
    在CMD中运行Python文件
  • 原文地址:https://www.cnblogs.com/shengjia/p/10397180.html
Copyright © 2020-2023  润新知