zoukankan      html  css  js  c++  java
  • 2,上传电影,udp,异常处理,socketserver

    今日内容
    1,作业:实现用户循环上传电影
    2,异常处理
    3,UDP通信
    4,SocketServer
    1,作业:
    客户端:
    import os
    import struct
    import socket
    import json


    client = socket.socket()
    client.connect(('127.0.0.1', 1688))

    while True:
    # 获取文件的绝对路径
    MOVIE_PATH = r'D:预习视频day12视频'
    # 获取电影列表目录
    movie_list = os.listdir(MOVIE_PATH)
    # 循环打印电影列表
    for i, movie in enumerate(movie_list):
    print(i, movie)
    # 让用户选择 电影列表编号
    choice = input('请输入商品编号:').strip()
    if choice.isdigit():
    choice = int(choice)
    if choice in range(0, len(movie_list)):
    # 获取用户选择的电影路径
    path = movie_list[choice]
    # 拼接电影的绝对路径
    path_dir = os.path.join(MOVIE_PATH,path)
    # 获取文件大小
    file_size = os.path.getsize(path_dir)
    # 创建一个字典
    d = {'name':'爱你一生千百惠.mp4', 'file_size': file_size, 'ps': '喝酒别开车!'}
    # 对该字典进行序列化
    json_dict = json.dumps(d)
    # 把序列化后的字符串转化为二进制数据
    dict_bytes = json_dict.encode('utf-8')
    # 创建字典报头
    header = struct.pack('i', len(dict_bytes))
    # 发送字典报头
    client.send(header)
    # 发送字典
    client.send(dict_bytes)
    # 循环发送真实的文件数据
    with open(path_dir, 'rb')as f:
    for line in f:
    client.send(line)
    else:
    print('选择不在范围之内')
    else:
    print('请选择数字!')
    服务端:
    import struct
    import socket
    import json

    server = socket.socket()
    server.bind(('127.0.0.1', 1688))
    server.listen(5)

    while True:
    conn, addr = server.accept()
    while True:
    try:
    # 接受报的规定长度
    header_len = conn.recv(4)
    # 先解析字典的报头
    header_len = struct.unpack('i',header_len)[0]
    # 接受字典
    header_dict = conn.recv(header_len)
    # 把接受到的二进制数据反序列化成json格式字典
    dict_json = json.loads(header_dict.decode('utf-8'))
    # 从字典中获取文件大小
    file_size = dict_json.get('file_size')
    # 循环接受并写入文件
    recv_size = 0
    # 在这里获取的是字典的名字
    with open(dict_json.get('name'), 'wb')as f:
    while recv_size < file_size:
    data = conn.recv(1024)
    # 读出来1024个字节的数据就将它写入文件
    f.write(data)
    # 直到写入文件的数据全部为被接受完的数据 ******************
    recv_size+=len(data)
    except ConnectionResetError as e:
    print(e)
    break
    conn.close()

    2:异常处理
    什么是异常?
    程序在运行过程中出现了不可预知的错误
    并且该错误没有对应的处理机制,那么就会以异常的形式表现出来
    造成的影响就是整个程序无法再正常运行

    异常的结构
    1.异常的类型:NAMEERROR
    2.异常的信息:name 'fdsdfsdf' is not defined
    3.异常的位置:Traceback (most recent call last):
    File "D:/python脱产10期视频/day29/01 异常处理.py", line 1, in <module>
    fdsdfsdf

    异常的种类
    分为两大类
    1.语法错误
    是你程序立刻就能解决的,这种错误是不能被容忍的
    语法上的错误 发现之后应该立刻解决

    2.逻辑错误 ****
    这种错是可以被容忍的 因为一眼看不出来
    针对逻辑上的错误 可以采用异常处理机制进行捕获,用try,except
    ps: except 后面跟错误类型

    常见的错误类型
    NAMERROR 名字错误 **********
    SyntaxError 语法错误 **********
    KeyError 键不存在 **********
    ValueError 值错误 **********
    IndexError 索引错误 **********
    try:
    name
    l = [1,2,3]
    l[111]
    d = {'name':'jason'}
    d['password']
    except NameError:
    print('NameError')
    except IndexError:
    print('indexerror')
    except KeyError:
    print('keyerror')

    ps:1,错误发生后,会立刻停止代码的运行,
    2,会走第一个except,只要出错。下面的except都不会走
    3,except BaseException: # 万能异常 所有的异常类型都被捕获
    Exception也是万能异常,他继承了BaseException
    如何避免
    异常处理
    在你认为可能会出现bug的代码块上方try一下:注意try内部的代码块越少越好 *****

    try:
    可能出错的代码
    except 出错的类型 as e: # 将报错信息赋值给变量e
    出错之后的处理机制 ================================




    try:
    # name
    l = [1,2,3]
    l[111]
    # d = {'name':'jason'}
    # d['password']
    except Exception: # 万能异常 所有的异常类型都被捕获
    print('老子天下无敌')
    else:
    print('被检测的代码没有任何的异常发生 才会走else')
    finally:
    print('无论被检测的代码有没有异常发生 都会在代码运行完毕之后执行


    主动抛异常
    if 'egon' == 'DSB':
    pass
    else:
    raise TypeError('尽说大实话')
    关键字raise就是主动抛出异常


    l = [1,2,3]
    assert len(l) < 0 # 断言 预言
    猜某个数据的状态 猜对了 不影响代码执行 正常走
    猜错了 直接报错

    l = [1,2,3]
    assert len(l) < 0 # 断言 预言
    猜某个数据的状态 猜对了 不影响代码执行 正常走
    猜错了 直接报错

    自定义异常
    9 自定义异常
    class MyError(BaseException):
    def __init__(self,msg):
    super().__init__()
    self.msg=msg
    def __str__(self):
    return '<dfsdf%ssdfsdaf>' %self.msg

    raise MyError('我自己定义的异常') # 主动抛出异常其实就是将异常类的对象


    3,UDP 协议
    1,udp 不会粘包,因为他是数据报协议,自带报头
    2,不需要建立链接,直接进行发送数据,没有双向通道,就像发送短信一样
    3,当服务端不存在时 ,也不会报错,客户端允许发空

    客户端:
    import socket

    client = socket.socket(type=socket.SOCK_DGRAM)

    server_addr = ('127.0.0.1',1688)
    while True:
    client.sendto(b'fggfgfghyhjh',server_addr)
    data, addr = client.recvfrom(1024)
    print('服务端发来的数据',data)
    print('服务端的地址',addr)
    服务端:
    import socket

    server = socket.socket(type=socket.SOCK_DGRAM)
    server.bind(('127.0.0.1', 1688))
    # udp 不需要设置半连接池,没有链接池这个概念
    # 没有双向通道,所以不需要accept ,直接通信循环
    while True:
    data, addr = server.recvfrom(1024) 接受数据
    print('数据', data) # 客户端发来的数据
    print(addr) # 客户端的ip地址和端口
    server.sendto(data.lower(),addr) 发送数据 # 数据和地址

    简易版本的qq案例:
    服务端:
    import socket

    server = socket.socket(type=socket.SOCK_DGRAM)
    server.bind(('127.0.0.1', 1688))

    while True:
    data, addr = server.recvfrom(1024)
    print(data.decode('utf-8'))
    msg = input('>>>>:')
    server.sendto(msg.encode('utf-8'),addr)

    客户端:
    import socket
    client = socket.socket(type=socket.SOCK_DGRAM)
    server_addr = ('127.0.0.1', 1688)

    while True:
    msg = input('>>>>:')
    msg = '来自客户端0的数据:%s'% msg
    client.sendto(msg.encode('utf-8'),server_addr)
    data, addr = client.recvfrom(1024)
    print(data.decode('utf-8'))

    4,SocketServer(让tcp支持并发,也可支持UDP)
    客户端:
    import socket

    client = socket.socket()
    client.connect(('127.0.0.1',8080))

    while True:
    client.send(b'hello')
    data = client.recv(1024)
    print(data.decode('utf-8'))
    服务端:
    import socketserver

    class MyServer(socketserver.BaseRequestHandler):
    def handle(self):
    while True:
    data = self.request.recv(1024)
    print(self.client_address)
    print(data.decode('utf-8'))
    self.request.send(data.upper())


    if __name__ == '__main__':
    # 创建一个tcp对象
    server = socketserver.ThreadingTCPServer(('127.0.0.1',1688),MyServer)
    server.serve_forever()
  • 相关阅读:
    “无法更新EntitySet“*****”,因为它有一个DefiningQuery,而元素中没有支持当前操作的元素”问题的解决方法
    Web.Config全攻略
    C#常用的正则
    Asp.Net MVC2 Json
    webservice+Jquery返回Json格式【原创】
    JAVA线程池介绍以及简单实例
    从程序员到项目经理(17):你不是一个人在战斗思维一换天地宽
    SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
    多表对应更新(跨服务器).sql
    sql导出excel.sql
  • 原文地址:https://www.cnblogs.com/Fzhiyuan/p/11324179.html
Copyright © 2011-2022 走看看