zoukankan      html  css  js  c++  java
  • 111

    # 1 .黏包现象   发送的两个数据黏在一起
    #2 .成因
        #发送端粘:和包机制
        #接受端粘 :接受不及时
        #数据与数据是无边界的流逝传输
    # 3解决黏包
        #自定义协议
            #struct模块
                #把任意长度的数据变成固定的4个字节
            #低级
                #先发送数据长度
                #在发送数据
            #高级
                #先把所有相发送的数据信息放在字典
                #发送字典的长度
                #发送字典
                #发送设计的数据
    #作业
        #1 默写 黏包协议
        #2 上传大文件 视频 文件 图片
                # 4个g
        #3 和你同桌 调通从你的计算机上传一个视频到你同桌电脑
        #4 进阶 : 带上登录 先登录 在上传
        
        
    作业

    登录:

    import sys
    import json
    import socket
    import hashlib
    
    def get_md5(username,password):
        md5 = hashlib.md5(username.encode('utf-8'))
        md5.update(password.encode('utf-8'))
        return md5.hexdigest()
    
    def login(dic_msg):
        print(dic_msg['user'], dic_msg['pwd'])
        with open('userinfo', encoding='utf-8') as f:
            for line in f:
                user, pwd = line.strip().split('|')
                print(pwd,get_md5(dic_msg['user'], dic_msg['pwd']))
                if user == dic_msg['user'] and pwd == get_md5(dic_msg['user'], dic_msg['pwd']):
                    return {'opt':'login','result':True}
            else:return {'opt':'login','result':False}
    
    sk= socket.socket()
    sk.bind(('127.0.0.1',9001))
    sk.listen()
    while True:
        conn,addr = sk.accept()
        msg = conn.recv(1024).decode('utf-8')
        dic_msg = json.loads(msg)
        if hasattr(sys.modules[__name__],dic_msg['operate']):
            ret = getattr(sys.modules[__name__],dic_msg['operate'])(dic_msg)
            content = json.dumps(ret).encode('utf-8')
            conn.send(content)
        conn.close()
    sk.close()
    server
    import json
    import socket
    import hashlib
    
    def get_md5(username,password):
        md5 = hashlib.md5(username[::2].encode('utf-8'))
        md5.update(password.encode('utf-8'))
        return md5.hexdigest()
    username = input('用户名 :')
    password = input('密  码 :')
    sk = socket.socket()
    sk.connect(('127.0.0.1',9001))
    msg = {'operate':'login',
           'user':username,
           'pwd':get_md5(username,password)}
    str_msg = json.dumps(msg)
    sk.send(str_msg.encode('utf-8'))
    content = sk.recv(1024)
    str_content = content.decode('utf-8')
    dic_content = json.loads(str_content)
    if dic_content['result']:
        print('登录成功')
    else:
        print('登录失败')
    sk.close()
    client

    usrinfo:

    alex|ee838c58e5bb3c9e687065edd0ec454f

    一对多聊天:

    import json
    import socket
    
    sk = socket.socket(type=socket.SOCK_DGRAM)
    sk.bind(('127.0.0.1',9001))
    user_info = {
        1234:('alex','33[1;32m'),
        5678:('宝元','33[1;31m'),
    }
    while True:
        msg,addr = sk.recvfrom(1024)
        str_msg = msg.decode('utf-8')
        dic_msg = json.loads(str_msg)
        code = dic_msg['code']
        content = dic_msg['msg']
        print('%s%s : %s33[0m'%(user_info[code][1],user_info[code][0],content))
        ret = input('>>>').encode('utf-8')
        sk.sendto(ret,addr)
    sk.close()
    server
    import json
    import socket
    
    sk = socket.socket(type=socket.SOCK_DGRAM)
    addr = ('127.0.0.1',9001)
    code = 5678
    while True:
        msg = input('>>>')
        if msg.upper() == 'Q': break
        send_msg = {'code':code,'msg':msg}
        str_msg = json.dumps(send_msg)
        sk.sendto(str_msg.encode('utf-8'),addr)
        ret = sk.recv(1024).decode('utf-8')
        if ret.upper() == 'Q': break
        print(ret)
    sk.close()
    client
    import json
    import socket
    
    sk = socket.socket(type=socket.SOCK_DGRAM)
    addr = ('127.0.0.1',9001)
    code = 1234
    while True:
        msg = input('>>>')
        if msg.upper() == 'Q':break
        send_msg = {'code':code,'msg':msg}
        str_msg = json.dumps(send_msg)
        sk.sendto(str_msg.encode('utf-8'),addr)
        ret = sk.recv(1024).decode('utf-8')
        if ret.upper() == 'Q':break
        print(ret)
    sk.close()
    client

    黏包server

    import struct
    import socket
    
    sk = socket.socket()
    sk.bind(('127.0.0.1',9001))
    sk.listen()
    
    conn,addr = sk.accept()
    num = conn.recv(4)
    num = struct.unpack('i',num)[0]
    file_name = conn.recv(num).decode('utf-8')
    filesize = conn.recv(4)
    filesize = struct.unpack('i',filesize)[0]
    with open(file_name,'wb') as f:
        content = conn.recv(filesize)
        f.write(content)
    
    conn.close()
    sk.cl
    import struct
    import socket
    
    sk = socket.socket()
    sk.bind(('127.0.0.1',9001))
    sk.listen()
    
    conn,addr = sk.accept()
    num = conn.recv(4)
    print(num)  #b'x0bx00x00x00'
    num = struct.unpack('i',num)[0] #元组第一个元素 后面的是点
    # num1 = struct.unpack('i',num)[1] #元组第一个元素 后面的是点
    print(num)  #11
    # print(num1)
    file_name = conn.recv(num).decode('utf-8')
    print(file_name)#2.作业.py
    filesize = conn.recv(4)
    print(filesize)#b'Hx01x00x00'
    filesize = struct.unpack('i',filesize)[0]
    print(filesize)#328
    with open(file_name,'wb') as f:
        content = conn.recv(filesize)
        f.write(content)
    conn.close()
    sk.close()
    server 收
    import struct
    import socket
    
    sk = socket.socket()
    sk.bind(('127.0.0.1',9001))
    sk.listen()
    
    conn,addr = sk.accept()
    num = conn.recv(4)
    print(num)  #b'x0bx00x00x00'
    num = struct.unpack('i',num)[0] #元组第一个元素 后面的是点
    # num1 = struct.unpack('i',num)[1] #元组第一个元素 后面的是点
    print(num)  #11
    # print(num1)
    file_name = conn.recv(num).decode('utf-8')
    print(file_name)#2.作业.py
    filesize = conn.recv(4)
    print(filesize)#b'Hx01x00x00'
    filesize = struct.unpack('i',filesize)[0]
    print(filesize)#328
    with open(file_name,'wb') as f:
        content = conn.recv(filesize)
        f.write(content)
    conn.close()
    sk.close()
    client 发三次 第三次包含了长度

    str 字符串   字节bytes   dumps 倾倒 load 装入

    a = '中文'.encode('utf-8')#encode 一下就是bytes 类型的
    print(a,type(a))#b'xe4xb8xadxe6x96x87' <class 'bytes'>
    b = a.decode('utf-8')   #decode 一下就是str类型的
    print(b,type(b))    #中文 <class 'str'>
    # dunps#倾倒  load#装入
    a = {'1':2,'2':3}
    import json
    b = json.dumps(a)       #倾倒乱糟糟一个''
    print(b,type(b))#{"1": 2, "2": 3} <class 'str'>
    c = json.loads(b)       #装入有规律的字典
    print(c,type(c))#{'1': 2, '2': 3} <class 'dict'>

    send 发送 必须是bytes  b''  和  i.encode('utf-8')  接受解码 成字符串 decode

     字典类型

    import json
    import struct
    import socket
    
    sk = socket.socket()
    sk.bind(('127.0.0.1',9001))
    sk.listen()
    
    conn,addr = sk.accept()
    num = conn.recv(4)
    num = struct.unpack('i',num)[0]
    str_dic = conn.recv(num).decode('utf-8')
    dic = json.loads(str_dic)
    with open(dic['filename'],'wb') as f:
        content = conn.recv(dic['filesize'])
        f.write(content)
    
    conn.close()
    sk.close()
    server 字典类型
    import os
    import json
    import struct
    import socket
    
    sk = socket.socket()
    sk.connect(('127.0.0.1',9001))
    
    filepath  = input('请输入文件路径 :')
    filename = os.path.basename(filepath)
    filesize = os.path.getsize(filepath)
    dic = {'filename':filename,'filesize':filesize}
    str_dic = json.dumps(dic)
    bytes_dic = str_dic.encode('utf-8')
    len_dic = len(bytes_dic)
    bytes_len = struct.pack('i',len_dic)
    sk.send(bytes_len)
    sk.send(bytes_dic)
    with open(filepath,'rb') as f:
        content = f.read()
        sk.send(content)
    sk.close()
    
    # 先发送字典的长度
    # 再发字典 {'filename':xxxx,'filesize':xxxxx}
    # 再发文件内容
    client
    import json
    import struct
    import socket
    
    sk = socket.socket()
    sk.bind(('127.0.0.1',9001))
    sk.listen()
    
    conn,addr = sk.accept()
    num = conn.recv(4)
    num = struct.unpack('i', num)[0]
    str_dic = conn.recv(num).decode('utf-8')
    dic = json.loads(str_dic)
    with open(dic['filename'],'wb') as f:
        content = conn.recv(dic['filesize'])
        f.write(content)
    
    conn.close()
    sk.close()

     

  • 相关阅读:
    shell脚本中判断上一个命令是否执行成功
    nginx 414 Request-URI Too Large
    nginx 重写URL尾部斜杠
    Linux shell 日期,时间相关的命令
    shell脚本中自定义日志记录到文件
    scanf后面跟一个getchar
    1.Tarball软件make与makefile详解(还需要补充)
    <>和“”的区别
    malloc,calloc,realloc,alloc
    toString()方法细节
  • 原文地址:https://www.cnblogs.com/Doner/p/10682760.html
Copyright © 2011-2022 走看看