• 文件上传下载-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)
  • 相关阅读:
    CNN(卷积神经网络)入门
    基于linux vim环境python代码自动补全
    Linux 基本bash命令
    基于pytorch的CNN、LSTM神经网络模型调参小结
    深度学习中Batch size对训练效果的影响
    argparse.ArgumentParser()用法解析
    大数据学习之Hive数据仓库 20
    centOS中安装MySQL超级方便简单的方法
    大数据学习之zookeeper案例节点动态上下线感知19
    大数据学习之zookeeper客户端的命令行及API操作18
  • 原文地址:https://www.cnblogs.com/sandy-123/p/10429335.html
Copyright © 2020-2023  润新知