网络编程 之socketserver、大文件传输、异常处理

  • 去幕布>>>
  • socketserver模块
    • 如何理解socketsever
      使用封装好的模块,直接调用其中的方法,来完成socket模块可以实现的方法
    • 如何使用
      import socketserver
      class MyServer(socketserver.BaseResetHandler)​​:
          def handle(self)​:
              while True:
                  data, sock = self.request
                  print(self.client_address)​​​​  # 客户端地址
                  peint(data.decode('utf-8'))​
                  sock.send(data.upper(), self.client_address)​
      if name == '__main__'​:
          # 只要客户端连接,就会自动交给自定义类中的handle方法去处理​
          # 创建一个基于UDP的对象​​
          server = sockserver.TreadingUDPServer(('127.0.0.1', 8080), MyServer)  
          server.server_forever​()  # 启动该服务对象
      服务端
      # 客户端
      import os, time
      
      clienr = socket.socket(type = socket.SPCK_DGRAM)​​​​​​
      server_sddress = ('127.0.0.1', 8080)
      
      while True:
          client.sendto(b'hello', server_address)
          data, addr = clinet.recvfrom(1024)​​​​
          print(data.decode('utf-8'), addr)​
          time.sleep()​
      客户端 
  • TCP和UDP之间的区别
        1,tcp传输数据使用字节流的方式传输,udp是数据报
        2,tcp会产生粘包现象,udp不会
        3,tcp对网络条件要求高,udp更适合实时传输
        4,tcp编程可以保证传输的可靠性,udp则不保证
        5,tcp使用listen accpet, udp不需要
        6,tcp使用recv send  
         udp使用recvfrom sendto
  • UDP基本使用 案例之循环对话
    # 服务端
    import socket
    
    server = socket.socket(type = socket.SOCK_DGRAM)​​  # UDP协议
    server.bind('127.0.0.1', 8080)  # UDP不需要设置半连接池,他没有半连接池的概念
    # 因为没有双向通道,不需要accept,直接就是通信循环即可​
    while True:
        data, addr = server..recvfrom​(1024)
        print('数据:', data)  # 客户端发来的信息
    ​​    print('地址:', addr)  # 客户端的地址
        server.sendto(data.upper(), addr)
    服务端
    # 客户端
    import socket
    
    client = socket.socket(type = socket.SOCK_GRAM​​​​)
    # 不需要建立连接,直接进入通信循环
    
    server_address = ('127.0.0.1', 8080)​​​
    while True:
        client.sendto(b'hello', server_address)​​
        data, addr = client.recvfrom(1024)
        print('服务端发来的数据:', data)​​
    ​    print('服务端的地址:', addr)
    客户端
  • UDP实现简单的QQ
    # 服务端
    import socket
    
    server = socket.socket(type = socket.SOCK_DGRAM)​​
    
    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_address = ​('127.0.0.1', 8080)
    
    while True:
        msg = input('>>>:')​​
        msg = '来自客户端1的消息:%s' ​%smsg
        clinet.sendto​(msg.encode('utf-8'), server_address)
        data, server_addr = client.recvfrom(1024)​
        ​print(data.decode('utf-8'))
    客户端
  • TCP实现 发送/上传 大文件
    # 服务端
    import socket, json, struct, os
    ​
    server = socket.socket()
    server.bind('127.0.0.1', 8080)​​​
    ​
    while True:
        conn, addr = server.accept()
    ​
        while True​​​​:
            try:
                dict_header = conn.recv(1024)
    ​            # 解析字典报头
                header_len = struct.unpack('i', header_len)[0]​
                # 再接收字典
                dict_bytes = ​​conn.recv(header_len)
                real_dict = json.loads(dict_bytes.decode('utf-8'))
                # 获取数据长度
                real_size = real_dict.get(file_size')​​​
    # 循环接收,写入文件
                while True:
                    recv_size = 0
    ​​​​                with open(real_dic.get('file_name'), 'wb')as f:
    ​​​​​                     while True:
                              ​data = server.recv(1024)
                           ​ ​  f.write(data)​
                         ​     ​​recv_size += len(data)
                        ​  print('上传成功!')​
    ​         except ConnectionResetError as e:
                  print(e)​
                  break
    conn.close()​​
    服务端
    # 客户端
    import socket, os, struct, json
    ​
    ​​​client = socket.socket()
    clinet.connect(('127.0.0.1', 8080))​
    ​
    while True:
          # 获取电影列表 循环展示
          MOVIE_DIR = r'path1'
          ​​​​​movie_list = os.listdir(MOVIE_DIR)
    ​
          ​​for i, movie in enumerate(movie_list, 1):
          ​​​​​      print​(i, movie)​​
          ​​​​​# 用户选择
          ​​​​​choice = input('input your choice>>>:')​
          ​​​​​# 判断choice
          ​​​​​if choice.isdigit() and int(choice) in range(1, len(movie_list) + 1):​​​
    ​​​      ​​​​​      ​​​​​# 获取用户想上传文件的名字
          ​​​​​      name = movie_list[int(choice)]
    ​​​​      ​​​​​      ​​​​​# 拼接文件的绝对路径
    ​​​      ​​​​​      ​​​​​​file_path = os.path.join(MOVIE_DIR, name)
    ​​​      ​​​​​      ​​​​​# 获取文件大小
    ​​​      ​​​​​      ​​​​​file_size = os.path.getsize(file_size)​
    ​​​      ​​​​​      ​​​​​# 定义一个字典​​
    ​​​      ​​​​​      ​​​​​res_d = {
    ​​​      ​​​​​      ​​​​​​​​      ​​​​​      ​​​​​'file_name': 'xxx.mp4',​
    ​​​      ​​​​​      ​​​​​​​​      ​​​​​      'file_size': file_size,
    ​​​      ​​​​​      ​​​​​​​​      ​​​​​      'msg'​​: '注意身体'
    ​​​      ​​​​​      ​​​​​​}​
    ​​​      ​​​​​       
    ​​​      ​​​​​      # 序列化字典
    ​​​      ​​​​​      json_d = json.dumps(res_d)
    ​​​      ​​​​​      bytes_d = json_d.encode('utf-8')
    ​​​      ​​​​​      # 制作字典报头
    ​​​​​​​​      ​​​​​      header_d= struct.pack('i', len(bytes_d))
    ​​​      ​​​​​      # 发送字典报头
    ​​​      ​​​​​      client.send(header_d)
    ​​​      ​​​​​      # 发送字典
    ​​​      ​​​​​      client.send(bytes_d)​​​
    ​
    ​​​      ​​​​​      # 发送数据(打开文件循环发送,一行一行地发送)​​
    ​​​      ​​​​​      while True:
    ​​​      ​​​​​      ​​​      ​​​​​  with open(file_size, 'rb') as f:
    ​​​      ​​​​​      ​​​      ​​​​​      ​​​    ​​​​​for line in f:
    ​​​      ​​​​​      ​​​      ​​​​​      ​​​      ​​​​​     client.send(line)​
          ​​​​​else:
          ​​​​​      ​​​​​print('请输入数字,且在可选范围内选择..')​​
    客户端
  • 异常处理
    • 什么是异常
      程序在运行过程中出现了不可预知的错误并且该错误没有对应的处理机制,
      那么就会以异常的形式表现出来
      造成的影响就是整个程序无法再正常运行​​
    • 异常的结构(例如没有定义age时,就要使用age)
      1.异常的类型  NAMEERROR
      2.异常的信息  name 'age' is not defined
      3.异常​​的位置  Traneback(most recent call last): file"xxx.py", line 1, in<modul> age
    • 异常的种类 两大类
      1.语法错误是修改程序就能立刻解决的,
      这种错误不能被容忍语法上的错误,应该在发现之后立刻解决
      2.逻辑错误这种错误可以被容忍,因为一眼看不出来针对逻辑上的错误
      可以采用异常处理机制进行捕获
      常见的错误类型:
      NAMEERROR     名字错误
      SyntaxError   语法错误
      KeyError      键不存在
      ValueError    值错误
      IndexError  ​​​​​​​​​​​​  索引错误
    • 如何避免异常
      使用异常处理:​在你认为可能会出现bug的代码块上方try一下,
      注意:try内部的代码块越少越好
      try:
          可能会出错的代码块
      except​​​​ 错误类型 as e:  # 将错误信息赋值给变量e
          出错后的处理机制(例如break)​

       

posted @ 2019-08-08 16:52  不在一城  阅读(627)  评论(0编辑  收藏  举报