ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

PYTHON2.day04

2019-02-18 18:39:19  阅读:227  来源: 互联网

标签:socket day04 fd IO sockfd 接字 data PYTHON2


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\n"%(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.py2019-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服务端

标签:socket,day04,fd,IO,sockfd,接字,data,PYTHON2
来源: https://www.cnblogs.com/shengjia/p/10397180.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有