• python 网络编程基础 day10


              概要:

                  上节课回顾

                  小知识点

                  python2.7多继承

                  IO多路复用

                  多线程、多进程

    上节课回顾:

    socekt
        1、导入模块
        2、创建socket
        3、Python3.0 发送字节,2.0 发送字符串
            send#发送一定数量,不一定全发送
                发送了多少 = send("ssssssdddddfffffffff") 
            sendall#sendall内部会调用send循环发送
                sendall:
                    while True:
                        10 = send("sssssdfdgsghhhjj")
                        10 = send("sssssdfdgsghhhjj")
            recv(2048) #上传文件时,最多接收2048
    send和sendall区别
    粘包问题
    
    socektserver
    
        1、自定义类
    
        2、必须自定义handle方法
    
          3、handle必须继承socketserver.BaseRequestHandler
    
          4、socketserver调用上面的类
    
          5、运行
    socketserver
    1、socket 发送字符串
        2、socket 发送文件
            客户端:
                文件大小
                发消息
            服务端:
                接收消息(文件大小)
                
        客户端:
            json -> 用户、密码 
            字符串
            
        服务端:
            用户验证(必须放在服务端)
            接收,subprocess>win>gbk编码的字节
            上传文件(大小)
            发消息:
        
        
        断点续传:
        seek
    上节课作业注意点

    小知识

    作用域

    java/C# 不可运行(name没定义)

    python/javascript 可以运行

    if 1 == 1:
        name = 'alex'
    print(name)  #可以输出
    
    for i in range(10):
        name1 = i
    print(name1)
    python中无块级作用域
    def func():
        name2 = 'QL'
    
    func()
    print(name2) #name2只在函数里生效此处报错
    python中以函数为作用域
    #python的作用域在执行之前已经确定
    name = 'alex'
    def f1():
        print(name)
    
    def f2():
        name = 'eric'
        f1()
    f2()   #name = 'alex
    
    
    #######################
    name = 'alex'
    def f1():
        print(name)
    
    def f2():
        name = 'eric'
        return f1
    ret = f2()
    ret()
    python作用域链由内向外直到找不到

    由新浪面试题引发的:

    #问题 print(a[1]())?
    a = [lambda :x for x in range(10)]
    
    ##########################
    #首先 for循环可以写成下面的形式
    #for循环10次 x >6 的 x+100 生成新的列表
    li = [x+100 for x in range(10) if x >6]
    print(li)
    
    #然后分析此表达式
    a = [lambda :x for x in range(10)]
    
    #a中的元素[函数,函数,函数]
    #函数在没有执行前,内部代码不执行。
    #?li[0],函数
    #?函数()
    #返回值是???
    print(a[1]())
    
    #上面的lambda表达式拆开写
    li = []
    for x in range(10):
        def fucn(): 
            return x    #fucn中没有x就到外面找
        li.append(fuco) #for循环过程中已经生成li函数列表,但是函数并没执行
        print(x)
    print(li[0]())      #当函数执行时才会用到x但此时x已经是循环之后到值9,所以li里所有元素都是9
    
    ####升级#########
    li = []
    for i in range(10):
        def fucn(x=i): #x=i执行了
            return x
        li.append(fucn)
     
    print(li[0]())

    python2.7多继承

    class A:
        def f2(self):
        print('A')
        
    class B(A):
        def f1(self):
        print('B')
    class C(A):
        def f1(self):
        print('C')
    class D(B):
        def f1(self):
        print('D')
    class E(C):
        def f2(self):
        print('E')
    class F(D,E):
        def f1(self):
        print('F')
        
    obj = F()
    obj.f2()
    
    #它寻找f2的顺序是  F--->D--->B--->A
    经典类
    class A:(object)
        def f2(self):
        print('A')
        
    class B(A):
        def f1(self):
        print('B')
    class C(A):
        def f1(self):
        print('C')
    class D(B):
        def f1(self):
        print('D')
    class E(C):
        def f2(self):
        print('E')
    class F(D,E):
        def f1(self):
        print('F')
        
    obj = F()
    obj.f2()
    #执行f2方法的顺序,F--->D--->B--->E--->C---A
    #A是父类,继承了object类。如果当前类或父类继承了object类,那么该类是新式类,否则式经典类
    新式类

    python 2.7默认不继承object(经典类,一条道走到黑;继承object是新式类和3.0找的方式一样)

    python 3.0默认继承object (广度优先)

    IO多路复用(IO不占用内存)

    概述:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。

      select,poll,epoll(系统底层提供的,select可以在win和Linux上执行,epoll不支持win)

      select有个数监听限制1024,内部机制是for循环监听,不止监听socket,还可以监听终端等等,但不能监听文件

      epoll 客户端主动告诉epoll有消息,效率高

    select

    监听socket对象内部是否变化了

    什么时候变化?连接或收发消息

    服务器端的socket对象发生变化->有新连接来了

    sk:有新连接来了(sk变化)····

    conn:要收“发”消息了(conn变化了)

    如何读写分离?

    import socket
    import select# 监听是否变化
    
    sk = socket.socket()
    sk.bind(('127.0.0.1',9999))
    sk.listen(5)
    
    while True:
        rlist,w,e, = select.select([sk,],[],[],1)
        print(rlist)
        #监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端来连接了,rlist中就是socket对象列表,[sk]
        #监听conn对象,如果conn发生变化,表示有新消息发送过来了,此时rlist的值为[客户端]
        for r in rlist:
    
            print(r)
            conn,address = r.accept()
            #conn其实也是socket对象
    
            conn.sendall(bytes('hello',encoding='utf-8'))
    
    rlist = [sk] ,rlist = [sk1],rlist = [sk1,sk]#发生变化
    
    rlist = [] #不变化 rlist是空
    sk_server select监听是否变化
    import socket
    
    sk = socket.socket()
    sk.connect(('127.0.0.1',9999))
    data = sk.recv(1024)
    print(data)
    
    while True:
        input(">>>:")
    sk.close()
    sk_client
    #伪并发,好比10086一个客服管理着所有电话,一个电话接听后没有说话,另一个电话响了,那么他这个电话不挂,去接另一个电话,如果这个电话一直在说话,那么下个电话就得等待
    import socket
    import select# 监听是否变化
    
    sk = socket.socket()
    sk.bind(('127.0.0.1',9999))
    sk.listen(5)
    
    inputs = [sk,]
    while True:
        rlist,w,e= select.select(inputs,[],[],1)
        print(len(inputs),len(rlist))
        for r in rlist:
            if r == sk:
                conn,address = r.accept()
                inputs.append(conn)
                conn.sendall(bytes('hello',encoding='utf-8'))
    
            else:
                try:    #客户端断开连接 服务器端移除监听
                    ret = r.recv(1024)
                    if not ret:
                        raise Exception('断开连接')
                except Exception as e:
                    inputs.remove(r)
    
    伪并发
    sk_server 伪并发
    import socket
    
    sk = socket.socket()
    sk.connect(('127.0.0.1',9999))
    data = sk.recv(1024)
    print(data)
    
    while True:
        inp = input(">>>:")
        sk.sendall(bytes(inp,encoding='utf-8'))
    sk.close()
    sk_client
    import socket
    import select# 监听是否变化
    
    sk = socket.socket()
    sk.bind(('127.0.0.1',9999))
    sk.listen(5)
    
    inputs = [sk,]
    outputs = [] #谁连接就添加到列表里
    while True:
        rlist,wlist,elist= select.select(inputs,outputs,[],1) #outputs里有什么 w就获取到什么,
        print(len(inputs),len(rlist),len(wlist),len(outputs))
        for r in rlist:
            if r == sk:
                conn,address = r.accept()
                inputs.append(conn)
                conn.sendall(bytes('hello',encoding='utf-8'))
    
            else:
                print('===========')
                try:
                    ret = r.recv(1024)
                    if not ret:
                        raise Exception('断开连接')
                    else:
                        outputs.append(r)
                except Exception as e:
                    inputs.remove(r)
        for w in wlist:
            w.sendall(bytes('response',encoding='utf-8')) #回复完消息 移除连接对象
            outputs.remove(w)
    sk_server 收发消息分开写
    import socket
    
    sk = socket.socket()
    sk.connect(('127.0.0.1',9999))
    data = sk.recv(1024)
    print(data)
    
    while True:
        inp = input(">>>:")
        sk.sendall(bytes(inp,encoding='utf-8'))
        print(sk.recv(1024))
    sk.close()
    sk_client
    import socket
    import select# 监听是否变化
    
    sk = socket.socket()
    sk.bind(('127.0.0.1',9999))
    sk.listen(5)
    
    inputs = [sk,]
    outputs = [] #谁连接就添加到列表里
    messages = {}
    while True:
        rlist,wlist,elist= select.select(inputs,outputs,[],1) #outputs里有什么 w就获取到什么,
        print(len(inputs),len(rlist),len(wlist),len(outputs))
        for r in rlist:
            if r == sk:
                conn,address = r.accept()
                inputs.append(conn)
                messages[conn] =[]
                conn.sendall(bytes('hello',encoding='utf-8'))
    
            else:
                print('===========')
                try:
                    ret = r.recv(1024)
                    if not ret:
                        raise Exception('断开连接')
                    else:
                        outputs.append(r)
                        messages[r].append(ret)
                except Exception as e: #客户端断开连接回返回错误提示
                    inputs.remove(r)
                    del messages[r] # 移除人名和对应的值
        for w in wlist:
            msg = messages[w].pop()
            resp = msg +bytes('response',encoding='utf-8')
            w.sendall(resp)
            outputs.remove(w)
    sk_server 回复客户端发来的消息+其他消息
    import socket
    
    sk = socket.socket()
    sk.connect(('127.0.0.1',9999))
    data = sk.recv(1024)
    print(data)
    
    while True:
        inp = input(">>>:")
        sk.sendall(bytes(inp,encoding='utf-8'))
        print(sk.recv(1024))
    sk.close()
    sk_client

    线程

    import time
    import threading
    #串行
    def f1(i):
        time.sleep(1)
        print(i)
    
    #创建线程并行
    
    t = threading.Thread(target=f1,args=(123,)) #
    t.setDaemon(True) #True表示主线程不等子线程
    t.start() #只是准备好被cpu调度,不代表当前线程立即执行
    t.join(2) #表示主线程到此,等待...直到子线程执行完毕(里面的参数2表示最多登录2秒,f1里是1秒那么这里就等1秒)
    print('end')
    #f1(1111)
    

      

  • 相关阅读:
    三次握手与四次挥手原理
    动态主机配置协议(DHCP)
    网络知识-OSI7层模型说明和相关协议
    企业面试题合集
    优先队列(priority_queue)自定义排序方法
    优先队列(priority_queue)自定义排序方法
    C. Playlist(权值线段树查询前k大和)
    C. Playlist(权值线段树查询前k大和)
    C++判断四个点能否构成正方形/矩阵
    C++判断四个点能否构成正方形/矩阵
  • 原文地址:https://www.cnblogs.com/QL8533/p/5659843.html
Copyright © 2020-2023  润新知