zoukankan      html  css  js  c++  java
  • day29 文件的上传和下载 socketserver(并发)

    文件上传的讲解:

    1 import subprocess
    2 
    3 res=subprocess.Popen("dir",
    4                      shell=True,
    5                      stderr=subprocess.PIPE,
    6                      stdout=subprocess.PIPE)
    7 
    8 
    9 print(res.stdout.read().decode("gbk"))
    server
     1 import socket
     2 import os
     3 import json   #序列化对象  : 把字典 列表变成字符串
     4 
     5 sock=socket.socket()
     6 sock.connect(("127.0.0.1",8800))
     7 
     8 
     9 while 1 :
    10     cmd=input("请输入命令:") # put 111.jpg
    11 
    12     action,filename=cmd.strip().split(" ")
    13     filesize=os.path.getsize(filename)
    14 
    15     file_info={
    16         "action": action,
    17         "filename": filename,
    18         "filesize": filesize,
    19     }
    20     file_info_json=json.dumps(file_info).encode("utf8")
    21     sock.send(file_info_json)
    22 
    23     # 确认服务端接收到了文件信息
    24     code=sock.recv(1024).decode("utf8")
    25     if code=="200":
    26         # 发送文件数据
    27         with open(filename,"rb") as f:
    28             for line in f:
    29                 sock.send(line)
    30     else:
    31         print("服务器异常!")
    32 
    33 
    34 '''
    35 
    36 
    37 '{.....}'   'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
    38 
    39 
    40 
    41 
    42 '''
    client
    对上传的文件进行加密校验:
     1 import struct
     2 import socket
     3 import json
     4 import hashlib
     5 
     6 sock=socket.socket()
     7 sock.bind(('127.0.0.1',8800))
     8 sock.listen(5)
     9 
    10 
    11 
    12 while 1:
    13     print("server is working....")
    14     conn,addr= sock.accept()
    15     while 1:
    16 
    17         # 接收json的打包长度
    18         file_info_length_pack=conn.recv(4)
    19         file_info_length=struct.unpack("i",file_info_length_pack)[0]
    20 
    21         # 接收json字符串
    22         file_info_json=conn.recv(file_info_length).decode("utf8")
    23         file_info=json.loads(file_info_json)
    24 
    25         action=file_info.get("action")
    26         filename=file_info.get("filename")
    27         filesize=file_info.get("filesize")
    28 
    29         # 循环接收文件
    30         md5=hashlib.md5()
    31         with open("put/"+filename,"wb") as f:
    32             recv_data_length=0
    33             while recv_data_length<filesize:
    34                 data=conn.recv(1024)
    35                 recv_data_length+=len(data)
    36                 f.write(data)
    37                 # MD5摘要
    38                 md5.update(data)
    39                 print("文件总大小:%s,已成功接收%s"%(filesize,recv_data_length))
    40 
    41         print("接收成功!")
    42         conn.send(b"OK")
    43         print(md5.hexdigest())
    44         md5_val=md5.hexdigest()
    45         client_md5=conn.recv(1024).decode("utf8")
    46         if md5_val==client_md5:
    47              conn.send(b"203")
    48         else:
    49              conn.send(b"204")
    server
    import socket
    import os
    import json
    import struct
    import hashlib
    
    sock=socket.socket()
    sock.connect(("127.0.0.1",8800))
    
    
    while 1 :
        cmd=input("请输入命令:") # put 111.jpg
    
        action,filename=cmd.strip().split(" ")
        filesize=os.path.getsize(filename)
    
        file_info={
            "action": action,
            "filename": filename,
            "filesize": filesize,
        }
        file_info_json=json.dumps(file_info).encode("utf8")
    
        ret=struct.pack("i",len(file_info_json))
        # 发送 file_info_json的打包长度
        sock.send(ret)
        # 发送 file_info_json字节串
        sock.send(file_info_json)
        # 发送 文件数据
        md5=hashlib.md5()
        with open(filename,"rb") as f:
            for line in f:
                sock.send(line)
                md5.update(line)
    
        data=sock.recv(1024)
        print(md5.hexdigest())
        md5_val=md5.hexdigest()
        sock.send(md5_val.encode("utf8"))
        is_valid=sock.recv(1024).decode('utf8')
        if is_valid=="203":
            print("文件完整!")
        else:
            print("文件上传失败!")
    client

     

    重要模块 socketserver

       内部使用IO多路复合,以及多线程、多进程,从而实现并发处理多个客户端请求的服务器

    ThreadingTCPServer

    ThreadingTCPServer实现的Soket服务器内部会为每个client创建一个 “线程”,该线程用来和客户端进行交互

    1、ThreadingTCPServer基础

    使用ThreadingTCPServer:

    • 创建一个继承自 SocketServer.BaseRequestHandler 的类
    • 类中必须定义一个名称为 handle 的方法
    • 启动ThreadingTCPServer
    import SocketServer
    
    class MyServer(SocketServer.BaseRequestHandler):
    
        def handle(self):
            # print self.request,self.client_address,self.server
            conn = self.request
            conn.sendall('欢迎致电 10086,请输入1xxx,0转人工服务.')
            Flag = True
            while Flag:
                data = conn.recv(1024)
                if data == 'exit':
                    Flag = False
                elif data == '0':
                    conn.sendall('通过可能会被录音.balabala一大推')
                else:
                    conn.sendall('请重新输入.')
    
    
    if __name__ == '__main__':
        server = SocketServer.ThreadingTCPServer(('127.0.0.1',8009),MyServer)
        server.serve_forever()
    
    SocketServer实现服务器
    View Code
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import socket
    
    
    ip_port = ('127.0.0.1',8009)
    sk = socket.socket()
    sk.connect(ip_port)
    sk.settimeout(5)
    
    while True:
        data = sk.recv(1024)
        print 'receive:',data
        inp = raw_input('please input:')
        sk.sendall(inp)
        if inp == 'exit':
            break
    
    sk.close()
    
    客户端
    客户端

     SocketServer的ThreadingTCPServer之所以可以同时处理请求得益于 select 和 os.fork 两个东西,其实本质上就是在服务器端为每一个客户端创建一个进程,当前新创建的进程用来处理对应客户端的请求,所以,可以支持同时n个客户端链接(长连接)

  • 相关阅读:
    AWS IoT Greengrass:配置安装 AWS CLI
    AWS IoT Greengrass:如何使用 AWS 管理控制台配置本地资源访问
    AWS IoT Greengrass 入门-模块6: 访问其他 AWS 服务
    AWS IoT Greengrass 入门-模块5:与设备影子交互
    AWS IoT Greengrass 入门-模块4:在 AWS IoT Greengrass 组中与设备交互
    AWS IoT Greengrass 入门-模块3(第 2 部分):AWS IoT Greengrass 上的 Lambda 函数
    Nginx 启动报错 (nginx: error while loading shared libraries: XXX: cannot open shared object file: No such file or directory ) 的解决办法
    自己制作一个简单的操作系统二[CherryOS]
    Linux-误删apt-get以及把aptitude换回
    完美解决phpstudy安装后mysql无法启动(无需删除原数据库,无需更改任何配置,无需更改端口)直接共存
  • 原文地址:https://www.cnblogs.com/xiaobai686/p/11789871.html
Copyright © 2011-2022 走看看