zoukankan      html  css  js  c++  java
  • 文件上传下载-UDP协议-socketserver并发

    recv原理

    1.验证服务端缓冲区数据没有取完,又执行了recv执行,recv会继续取值。

    复制代码
    # 服务器:
    import socket
    
    phone =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    phone.bind(('127.0.0.1',8080))
    phone.listen(5)
    conn, client_addr = phone.accept()
    from_client_data1 = conn.recv(2)
    print(from_client_data1)
    from_client_data2 = conn.recv(2)
    print(from_client_data2)
    from_client_data3 = conn.recv(1)
    print(from_client_data3)
    conn.close()
    phone.close()
    
    # 客户端:
    import socket
    import time
    phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    phone.connect(('127.0.0.1',8080))
    phone.send('hello'.encode('utf-8'))
    time.sleep(20)
    phone.close()
    复制代码

     2.验证服务端缓冲区取完了,又执行了recv执行,此时客户端20秒内不关闭的前提下,recv处于阻塞状态

    复制代码
    # 服务端:
    import socket
    
    phone =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    phone.bind(('127.0.0.1',8080))
    phone.listen(5)
    conn, client_addr = phone.accept()
    from_client_data = conn.recv(1024)
    print(from_client_data)
    print(111)
    conn.recv(1024) # 此时程序阻塞20秒左右,因为缓冲区的数据取完了,并且20秒内,客户端没有关闭。
    print(222)
    
    conn.close()
    phone.close()
    
    
    # 客户端:
    import socket
    import time
    phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    phone.connect(('127.0.0.1',8080))
    phone.send('hello'.encode('utf-8'))
    time.sleep(20)
    phone.close()
    复制代码

    3. 服务端缓冲区的数据取完之后,又执行了recv执行,此时客户端处于关闭状态,则recv会取到空字符串。

    复制代码
    # 服务端:
    import socket
    
    phone =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    phone.bind(('127.0.0.1',8080))
    phone.listen(5)
    conn, client_addr = phone.accept()
    from_client_data1 = conn.recv(1024)
    print(from_client_data1)
    from_client_data2 = conn.recv(1024)
    print(from_client_data2)
    from_client_data3 = conn.recv(1024)
    print(from_client_data3)
    conn.close()
    phone.close()
    
    
    # 客户端:
    import socket
    import time
    phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    phone.connect(('127.0.0.1',8080))
    phone.send('hello'.encode('utf-8'))
    phone.close()
    复制代码

     用户登录功能实现:

    复制代码
    用户登录作业用tcp协议下的socket完成:
    1,服务端:
        等待客户端来发送数据:用户名,密码。
        本地文件汇总查看用户名密码是否合法。
        合法:登录成功。
        否则:用户名或者密码错误。
    2,客户端:
        用户输入: 用户名,密码。
        发送到服务端进行校验。
    
    服务端:
    import socket
    
    server = socket.socket()
    server.bind(('127.0.0.1',9045))
    server.listen(5)
    try:
        while 1:
            conn,addr = server.accept()
            flag = 0
            while not flag:
                user_pwd = conn.recv(1024).decode('utf-8')
                with open ('userinfo',encoding='utf-8')as f:
                    for i in f:
                        if i.strip() == user_pwd:
                            conn.send('success'.encode('utf-8'))
                            flag =1
                            break
                    else:
                        conn.send('failed'.encode('utf-8'))
            conn.close()
    finally:
        server.close()
    
        
        
    客户端:
    import socket
    
    client = socket.socket()
    client.connect(('127.0.0.1',9045))
    while 1:
        user = input('用户名>>>').strip()
        pwd = input('密码>>>').strip()
        user_pwd = user + '|' + pwd
        client.send(user_pwd.encode('utf-8'))
        result = client.recv(1024)
        if result == b'success':
            print('登录成功')
            break
        else:
            print('用户名或密码错误')
    client.close()
    复制代码

     上传功能实现:

    复制代码
    服务端:
    import socket
    import json
    import struct
    import os
    
    server = socket.socket()
    server.bind(('127.0.0.1',9345))
    server.listen()
    
    file_base_path = 'D:上传下载'
    conn,addr = server.accept()
    
    head_dic_json_bytes_struct = conn.recv(4)    #接收4个字节
    head_dic_json_bytes_len = struct.unpack('i',head_dic_json_bytes_struct)[0]   # 转换成int长度
    head_dic_json_bytes = conn.recv(head_dic_json_bytes_len)    # 接收报头字典的字节
    head_dic_json = head_dic_json_bytes.decode('utf-8')        # 转换成json字符串
    head_dic = json.loads(head_dic_json)                        # 转换成报头字典
    
    file_path = os.path.join(file_base_path,head_dic['file_name'])
    with open(file_path,mode='wb')as f:
        total_data_size = 0
        while total_data_size < head_dic['file_size']:
            every_data = conn.recv(1024)
            f.write(every_data)
            total_data_size += len(every_data)
    
    conn.close()
    server.close()
    
    客户端:
    import socket
    import json
    import struct
    import os
    
    client = socket.socket()
    client.connect(('127.0.0.1',9345))
    #1.自定制报头
    head_dic = {
        'file_name':'今日总结.mp4',
        'file_path':r'F:workspace_pythons19day30文件上传今日总结.mp4',
        'file_size':None
    }
    head_dic['file_size'] = os.path.getsize(head_dic['file_path'])
    head_dic_json =json.dumps(head_dic)       #转换成json字符串
    head_dic_json_bytes = head_dic_json.encode('utf-8')   #将字符串转换成字节
    head_dic_json_bytes_struct = struct.pack('i',len(head_dic_json_bytes))   #转换成4个字节
    client.send(head_dic_json_bytes_struct)
    client.send(head_dic_json_bytes)
    with open(head_dic['file_name'],mode='rb')as f1:
        total_data_size = 0
        while total_data_size < head_dic['file_size']:
            every_data = f1.read(1024)
            client.send(every_data)
            total_data_size += len(every_data)
    client.close()
    复制代码

    基于UDP协议的socket

    TCP协议有回执,丢包跟网络相关(网络断开或者遭遇抓包)

    UDP协议无阻塞,没有粘包现象

    复制代码
    服务端:
    import socket
    server = socket.socket(type=socket.SOCK_DGRAM)  # udp协议
    server.bind(('127.0.0.1',8848))
    try:
        while 1:
            client_data, client_address = server.recvfrom(1024)
            print('来自%s消息: %s'%(client_address,client_data.decode('utf-8')))
            to_client_data = input('回复:').strip().encode('utf-8')
            server.sendto(to_client_data,client_address)
    finally:
        server.close()
        
    客户端:
    import socket
    client = socket.socket(type=socket.SOCK_DGRAM)  # udp协议
    while 1:
        to_server_data = input('给服务端发送:').strip().encode('utf-8')
        client.sendto(to_server_data,('127.0.0.1',8848))
        server_data, server_address = client.recvfrom(1024)
        print('33[1;35;0m来自%s的信息: %s33[0m' %(server_address,server_data.decode('utf-8')))
    复制代码

    socketserver

    复制代码
    服务端:
    import socketserver
    
    class MyServer(socketserver.BaseRequestHandler):   # MyServer类名不固定,但是必须要继承socketserver.BaseRequestHandler
    
        def handle(self):  # handle方法名固定写法
            # self.request conn
            while 1:
                from_client_data = self.request.recv(1024)
                print(from_client_data.decode('utf-8'))
                to_client_data = input('>>>').strip().encode('utf-8')
                self.request.send(to_client_data)
    
    
    if __name__ == '__main__':
        ip_port = ('127.0.0.1', 8888)
        socketserver.TCPServer.allow_reuse_address = True
        server = socketserver.ThreadingTCPServer(ip_port,MyServer)  # 固定写法((ip地址,端口),MyServer)
        # 源码显示:上一行代码: 创建socket对象,绑定ip地址和端口,监听
        server.serve_forever()
    
        
    客户端:
    import socket
    client = socket.socket()
    client.connect(('127.0.0.1',8888))
    
    while 1:
        to_server_data = input('>>>').strip().encode('utf-8')
        client.send(to_server_data)
        from_server_data = client.recv(1024).decode('utf-8')
        print(from_server_data)
  • 相关阅读:
    stenciljs 学习四 组件装饰器
    stenciljs 学习三 组件生命周期
    stenciljs 学习二 pwa 简单应用开发
    stenciljs ionic 团队开发的方便web 组件框架
    stenciljs 学习一 web 组件开发
    使用npm init快速创建web 应用
    adnanh webhook 框架 hook rule
    adnanh webhook 框架 hook 定义
    adnanh webhook 框架request values 说明
    adnanh webhook 框架execute-command 以及参数传递处理
  • 原文地址:https://www.cnblogs.com/sandy-123/p/10429335.html
Copyright © 2011-2022 走看看