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)

  

原文地址:https://www.cnblogs.com/QL8533/p/5659843.html