• 网络编程总结


    一.osi七层模型

    应用层 http https ssl smtp ftp

    表示层,会话层  

    传输层 tcp udp   端口信息 四层路由器 四层交换机

    # tcp
    # 可靠的 面向连接的 全双工的 流式传输 效率低
    # 三次握手和四次挥手
    # 三次握手
    # 把图背下来 syn ack
    # 四次挥手
    # 把图背下来 fin ack
    # 黏包 : (自定义协议)先发送数据的长度,再发送数据
    # udp 效率高 不可靠 无连接 基于数据包的传输 能够传输的数据的长度有限

    网络层  ipv4协议192.168.0.1 ipv6协议 ff2312:f5242:12:1:1:1 网关地址 子网掩码 路由器 三层交换机

    数据链路层 :arp (通过ip地址找到mac地址),rarp(通过mac地址找ip地址) 网卡 交换机

    物理层

    三次握手,四次挥手

     有syn  ack  fin  三种

    手写socket

    # 手写socket
    # server - tcp
    import socket
    # sk = socket.socket()
    # sk.bind(('127.0.0.1',9000))
    # sk.listen()
    #
    # # while True表示能够和多个client通信
    # conn,adds = sk.accept()  # 建立三次握手的过程
    # # while True表示能够和一个client说多句话
    # conn.recv(1024)
    # conn.send(b'xxx')
    # conn.close()
    # sk.close()  # 四次挥手中的两手
    
    # client -tcp
    # import socket
    # sk = socket.socket()
    # sk.connect(('127.0.0.1',9000))
    #
    # sk.send(b'hello')
    # sk.recv(1024)
    # sk.close()   # 四次挥手中的两手
    
    # server -udp
    # import socket
    # sk = socket.socket(type=socket.SOCK_DGRAM)
    # sk.bind(('127.0.0.1',9000))
    # while True:
    #     msg,cli_addr = sk.recvfrom(1024)
    #     sk.sendto(msg,cli_addr)
    # sk.close()
    
    # clients -udp
    # import socket
    # sk = socket.socket(type=socket.SOCK_DGRAM)
    # sk.sendto(b'msg',('127.0.0.1',9000))
    # msg,_ = sk.recvfrom(1024)
    # print(msg)
    # sk.close()

    操作系统:

    异步同步阻塞非阻塞并发并行
    并发和并行
    并行 能利用多核 同一时刻 有多个任务在CPU上同时执行 多任务
    并发 不能利用多核 同一时间段内 有多个任务在一个CPU上轮流被执行 一个cup一直使用

     同步和异步

    同步 当我执行一个任务  需要等待这个任务的结果才能继续执行下一个任务
    异步 当我执行某一个任务 不需要等待这个任务的结果 就可以继续执行下一个任务

    阻塞和非阻塞
    
    
    非阻塞 : cpu一直在工作
    阻塞 : CPU不工作 recv recvfrom accept input sleep


    io操作

    input : input read recv recvfrom accept connet close
    output: write send sendto connet accept close
    
    
    # 同步阻塞   等待不调度cup
    # def func():
    #     import time
    #     time.sleep(1)
    #
    # def func2():
    #     func()
    #     print(123)
    # func2()
    
    # 同步非阻塞  等待调度cup
    # def func():
    #     a = 1
    #     b= a+1
    #     return b
    # def func2():
    #     func()
    #     print(123)
    # func2()
    
    # 异步阻塞  不等待不调度cup
    # import time
    # import threading
    # def func():
    #     time.sleep(1)
    # t_l = []
    # for i in range(10):
    #     t = threading.Thread(target=func)
    #     t.start()
    #     t_l.append(t)
    # for t in t_l:t.join()
    
    
    # 异步非阻塞
    # 我调用一个函数 不等待这个函数的结果
    # 并且我能一直利用cpu
    
    
    
     


     异步非阻塞:

    异步:不等待结果

    非阻塞:一致调度cpu

     关于io多路复用

    作用:在windows中通过select 进行监控   linux 下通过pool  epool监控

    # 操作系统中的IO多路复用
    # select poll epoll
    # select windows
    # poll epoll linux
    # epoll最好

    # io多路复用
    # 代理所有的网络对象,帮助我们监听有哪一个对象发生了注册事件(读写异常),然后通知程序,去进行相应的处理

    # selectors模块
    # 能够有效的利用poll和epoll前提是你所在的操作系统是有这两个机制的
    # 自动的识别当前操作系统中我们能用的最好的机制

    select模块使用
    from socket import *
    import selectors
    
    sel=selectors.DefaultSelector()
    def accept(sk,mask):
        conn,addr=sk.accept()
        sel.register(conn,selectors.EVENT_READ,read)
    
    def read(conn,mask):
        try:
            data=conn.recv(1024)
            if not data:
                print('closing',conn)
                sel.unregister(conn)
                conn.close()
                return
            conn.send(data.upper()+b'_SB')
        except Exception:
            print('closing', conn)
            sel.unregister(conn)
            conn.close()
    
    sk=socket(AF_INET,SOCK_STREAM)
    sk.bind(('127.0.0.1',8088))
    sk.listen(5)
    sk.setblocking(False)
    
    sel.register(sk,selectors.EVENT_READ,accept) #相当于网select的读列表里append了一个文件句柄server_fileobj,并且绑定了一个回调函数accept
    
    while True:
        events=sel.select() # 代理在这里等待,等events事件来,一旦等来了 那么一定是有新的链接 来 或者是有发送给conn的数据来
        for sel_obj,mask in events:
            callback=sel_obj.data #callback=accpet/read
            callback(sel_obj.fileobj,mask) #accpet(server_fileobj,1)
    
    
    

    # select 只能使用select
    # selector 能用select poll epoll
    # select 采用轮询,能够处理的对象的个数有限
    # poll 采用轮询,能够处理的对象的个数无限的
    # epoll 回调
    # TCP协议
    # 监听多个sk,conn对象,谁的数据先来,我就通知谁来处理
    # 好处是什么
    # 把很个等待变成一个等待,有一个代理替我们来接收所有的请求

    线程/进程/协程

     在正常的编程语言中
    进程 是计算机中最小资源分配单位
    数据隔离 开销(开启 销毁 切换)大 内存级别数据安全 但是文件操作数据库操作数据不安全
    manager : 数据共享
    IPC(inter process communication):队列消息队列memcache abbitmq edis
    管道 : 基于socket + pickle
    原生的queue : 基于文件(管道 + 锁)
    第三方工具 : 基于网络稳定性更强
    线程 计算机中能被CPU调度的最小单位
    数据共享 开销(开启 销毁 切换)小 数据不安全 数据共享程序可能会同时去操作一个变量
    协程 本质是一条线程 协程任务对于操作系统来说不可见 协程是用户级的单位
    数据共享 开销非常小(函数的调用的速度一样快) 数据绝对安全
    在Cpython解释器下
    进程
    线程 不能利用多核 (flask django) : 文件操作更快
    GIL锁 : 全局解释器锁,锁的是线程,保证了同一个进程中的多个线程之间只有一个线程能访问CPU
    限制了一个python进程中的多线程不能利用多核
    无法处理高计算型的任务
    解决方案 开多进程
    协程(tonado tiwsted sanic scrapy) : 所有的time.sleep socket 协程更快
    一条线程
    指的是程序能够在多个协程任务之间来回切换
    如果在程序中遇到io就切换去执行另一个程序,实现了使用协程来规避io,提高cpu的使用率

     yield协程

    # def func():
    #     yield 1
    #     print(123)
    #     yield 2
    # def func2():
    #     g = func()
    #     g.__next__()
            # asyncio 基于yield关键字gevent 基于greenlet来完成的
            # aiohttp
  • 相关阅读:
    【MySQL】【2】数字排序问题
    【MySQL】【1】表中存在重复记录,删除保留其中一条
    poj 1811 Prim test
    Yours 的博客开张啦!
    P1044
    P1103
    hustwinter1-B
    hustwinterC
    hustwinter1-A
    hdu 2138 How many prime numbers
  • 原文地址:https://www.cnblogs.com/zhangqing979797/p/10533085.html
Copyright © 2020-2023  润新知