zoukankan      html  css  js  c++  java
  • day30 UDP协议

    本周安排

    周二 socket编程
    周三 粘包处理
    周四 选课系统
        并发编程
    周五多道技术 多进程
    周六 IPC 互斥锁

    常用模块 os* 操作系统 多数是文件操作 os.path 处理文件路径 shutil 高级文件处理模块 用起来更方便 sys 解释器相关 json* 一种序列化方式 json可以支持跨平台 pickle 一种序列化方式 仅在python可用 re* 正则表达式 用于处理字符串 主要是查找 匹配 验证 爬虫中 验证用户输入是否合法 hashlib* hash一种算法 输入一段任意长度的数据 输出一段固定长度的字符 也称之为特征码 用于加密 和 数据校验

    logging* 输出日志(程序运行的日记 是为了 日后出现问题 有迹可循)  用字典来配置  需包含 handler formater filter logger
    
    configparser   解析配置文件的模块   配置文件中只能有分区个选项
    
    xml  可扩展标记语言  其优势在于 可以自定义文档的结构 如HTML中有头有尾
    学习的重点是如何读取xml文档 并找到需要的标签
    
    time*  时间相关的 time.time() 获取时间戳    time.sleep() 让程序休眠指定时间
    
    subproces  子进程   由一个正在运行的程序开启的另一个程序 称之为子进程  当当前程序 无法处理用户请求 但是另一个程序可以处理时
    qq 中点击网页链接  会打开浏览器
    
    random* 随机数相关    抽奖   验证码  随机点名
    
    shelve  序列化方式  只有一个open函数
    其使用方式与字典一致   相当于一个自带序列化的字典

    面向对象 一种编程思想 核心概念 类与对象 对象是什么? 具备某些特征和技能的结合体 是实际存在的 类是 一系列具备相同特征和技能的集合体 是一种抽象概念

    三大特性
        封装
           隐藏内部实现细节 多外提供使用接口
           提高安全性 隔离复杂度  明确区分内外
           被封装的函数和属性 只能在当前类中使用
        继承
            是一种类与类之间的关系
            有了继承关系后 子类可以使用父类中已经存在的属性和方法
            其目的是减少代码冗余
            python 可以多继承
            属性查找顺序按照mro列表的顺序
                c3算法  如果存在菱形继承  先深度 (遇见了公共父类)在广度
                           不存在菱形 则 深度优先
        多态
            一个事物具备多种形态
            例如一个动物 有多种形态  如 猪狗牛羊
            不同的对象具备相同的方法  会产生不同结果
        
            要实现多态性 需要 先抽象得到到公共父类   然后子类去继承父类 并且覆盖父类中声明的方法
            abc模块可以强制子类必须实现父类的方法
    
            python中推荐鸭子类型   只要具备相同的方法就可以看做同一个类
    
         绑定方法
            对象绑定方法
            类绑定方法
            绑定给谁 就由谁来调用 并且在调用时 自动传入 对象或者类
    
         非绑定方法
            就是一个普通的函数
    
         面向对象的精髓 就是 把数据和处理数据的方法进行绑定

    异常 什么是异常 程序运行的时候出现了错误 程序会立即停止执行 为什么要学习异常 是为了保证程序可以正常执行结束 为了提高程序的健壮性 如何处理异常 try 可能出现异常的代码 except 异常的类型 打印异常信息 尝试处理异常

    else
        没有出现异常时执行
    finally
        无论是否出现异常 最后都会执行
        可以做清理操作
    
    自定义异常类型
        继承Exception
    主动抛出异常
        raise 任何Exception的子类 或者 其对象
    
    万能异常
        Exception 一定要打印异常信息
    
    异常组成
        异常的类型
        异常的值
        追踪信息
    
        找最后一行 把它翻译一下
        如果最后一行不是你写的而是模块内部的 那就找你写最后一行

    网络编程

    编写基于网络通讯的应用程序 1.七层模型 应用层

    传输层
            TCP/UDP工作在传输层
            要求 要联网的应用程序必具备端口号
            用于定位某台计算机上的某个应用程序
            TCP
            三次握手  建立连接
            四次挥手  断开连接
            为了保证数据的完整性
    
        网络层
            ip协议
            ip地址 四个十进制数 前三个是网络号 后一位是主机号  主机号为1是网关
            网关之间通过路由协议来找到对方
    
            有了ip之后 可以在全世界范围内定为到一台计算机
    
        链路层
            解析二进制的数据
            以太网协议工作在该层
            规定了二进制数据的分组方式
            一段二进制数据称之为数据帧  1518
            包含 head和data
    
            还规定了一个计算机必须有MAC地址  通过MAC就能定位局域网内的一台计算机
    
        物理层: 物理传输介质
            网线 光纤  无线网络
            能传输二进制数据
    
    recv(1024)阻塞:直到操作系统缓冲区有数据为止

    基础班

    服务器端
    
    import socket
    
    # 买手机 默认得到是一个TCP的socket
    server = socket.socket()
    
    # 两行代码的效果是一样的
    # socket的家族   AF_INET
    # socket的类型
    # SOCK_STREAM 对应的是TCP     SOCK_DGRAM 对应的是UDP
    
    # server = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
    # 创建基于UDP的socket
    # server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
    
    
    server.bind(("127.0.0.1",16888))  # 绑定手机卡
    
    server.listen() # 开始待机
    
    # 得到对方的socket对象与地址
    client,addr = server.accept() # 接收通话请求 # 该函数会阻塞 直到有连接请求过来
    
    
    print("==========")
    # buffersize 表示应用程序的缓冲区大小     recv其实是 从系统缓冲区读取数据到应用程序
    data = client.recv(1024)   # 该函数会阻塞 直到操作缓冲区有数据位置
    print("==========")
    
    print("收到客户端发来的数据:%s" % data.decode("utf-8"))
    
    # 发生的数据必须为bytes类型
    client.send(data)
    
    
    client.close() #挂断电话
    
    server.close() # 关机

    普通版 客户端

    import socket
    
    client = socket.socket()
    
    client.connect(("127.0.0.1",16888))
    
    client.send("hello 服务器".encode("utf-8"))
    
    
    print("===================")
    data = client.recv(1024)   # 该函数会阻塞 直到操作缓冲区有数据位置
    print("===================")
    
    print("收到服务器:%s" % data.decode("utf-8"))
    
    
    client.close()

    服务器 循环版

    import socket
    
    # 买手机 默认得到是一个TCP的socket
    server = socket.socket()
    
    # 两行代码的效果是一样的
    # socket的家族   AF_INET
    # socket的类型
    # SOCK_STREAM 对应的是TCP     SOCK_DGRAM 对应的是UDP
    
    # server = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
    # 创建基于UDP的socket
    # server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
    
    
    server.bind(("127.0.0.1",16888))  # 绑定手机卡
    
    server.listen() # 开始待机
    
    # 连接循环 可以不断接受新连接
    while True:
        client, addr = server.accept()
    
        # 通讯循环 可以不断的收发数据
        while True:
            try:
                # 如果是windows 对方强行关闭连接 会抛出异常
                # 如果是linux 不会抛出异常 会死循环收到空的数据包
                data = client.recv(1024)
                if not data:
                    client.close()
                    break
    
                print("收到客户端发来的数据:%s" % data.decode("utf-8"))
                client.send(data)
            except ConnectionResetError:
                print("客户端强行关闭了连接")
                client.close()
                break
    client.close() #挂断电话
    server.close() # 关机

    客户端 循环版

    import socket
    
    client = socket.socket()
    
    client.connect(("127.0.0.1",16888))
    
    while True:
        msg = input(">:")
        client.send(msg.encode("utf-8"))
        data = client.recv(1024)
        print("收到服务器:%s" % data.decode("utf-8"))
    
    client.close()

    UDP 服务端

    import socket
    
    # UDP协议 在创建socket是 只有一个类型不同
    server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,proto=0)
    
    server.bind(("127.0.0.1",8888))
    
    
    while True:
        data,addr = server.recvfrom(1024) # 阻塞 直到收到数据为止
        print("收到来自%s的消息:%s" % (data.decode("utf-8"),addr[0]))
        # 返回值为 数据 和 对方ip地址 和端口号
        server.sendto(data.upper(),addr)
    
    print(res)
    server.close()

    UDP客户端

    import socket
    
    client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
    
    while True:
        data = input(">>:").encode("utf-8")
        client.sendto(data,("127.0.0.1",8888))
        d,addr = client.recvfrom(1024)
        print(d.decode("utf-8"))
    
    client.close()

    半连接池

    服务端保存的未完成三次握手的连接的数量,超过一定数量后,再有新的连接请求过来,就不处理了,让请求等待
    
    服务器端模拟
    
    import  socket
    
    server = socket.socket()
    
    server.bind(("127.0.0.1",8888))
    
    # 参数可以设置最大的半连接数   最大5个
    server.listen()
    
    import time
    while True:
        time.sleep(0.5)
  • 相关阅读:
    AVOID "throw e" !!!
    C++基本功: 全面掌握const, volatile 和 mutable关键字
    转贴:asp.netN层代码示例
    管理强类型生成器(Mgmtclassgen.exe) MSDN
    WMI 例子,获取MAC地址
    SQL Server: convert varbinary to varchar
    C++: memset, memcpy 和strcpy的根本区别
    巧妙突破win2003系统的种种限制
    Question about sql server's linked server
    iOS APP开发概述学习笔记001
  • 原文地址:https://www.cnblogs.com/shanau2/p/10175111.html
Copyright © 2011-2022 走看看