python全栈学习--day36(socket验证客户端的合法性、 并发编程)

粘包现象
粘包现象的成因:
tcp协议的特点,面向流的,为了传输可靠传输,所以有很多优化机制。
无边界 所有在连接建立的基础上传递的数据之间没有界限
收发消息很有可能不完全相等
缓存机制,导致没发过去的消息会在发送端缓存
没有接收完的消息会在接收端缓存

解决:
给应用层定制协议
先发送一个定长的可以表示待发送数据长度的bytes 先接收一个固定长度
在发送要发送的数据 在按照长度接收数据


方案二:
先发送一个定长表示待发送字典长度的bytes (先接收一个固定长度)
再发送要发送字典(再按照长度接收字典)
在发送文件 (再根据字典中的信息接收相应的内容)

####大文件传输实例

实例一:

import os
import json
import struct
import socket

#
sk = socket.socket()
sk.bind(('192.168.11.36',9000))
sk.listen()

conn,addr = sk.accept()
print(addr)
dic = {'filename':' D:\战狼.rmvb',
        'filesize':os.path.getsize(r' D:\战狼.rmvb)}
str_dic = json.dumps(dic).encode('utf-8')
dic_len = struct.pack('i',len(str_dic))
conn.send(dic_len)
conn.send(str_dic)
with open(r' D:\战狼.rmvb','rb') as f:
    # content = f.read()
    while True:
        content = f.read(1024)
        if not content:break
        conn.send(content)
        # if not conn.send(content):break
conn.close()
sk.close()

  

import json
import struct
import socket

sk = socket.socket()
sk.connect(('192.168.11.36',9000))

dic_len = sk.recv(4)
dic_len = struct.unpack('i',dic_len)[0]
str_dic = sk.recv(dic_len).decode('utf-8')
dic = json.loads(str_dic)

with open(dic['filename'],'wb') as f:

    while True:
        content = sk.recv(dic['filesize'])
        if not content:break
        f.write(content)
sk.close()

示例二:

###加入MD5验证

#########server 端
import os
import json
import struct
import socket
import hashlib

md5 = hashlib.md5()
with open(r'D:\战狼.rmvb', 'rb') as f:
    while True:
        b = f.read(1024)
        if not b:
            break
        md5.update(b)
md5 = md5.hexdigest()
print(md5)

sk = socket.socket()
sk.bind(('127.0.0.1',9000))
sk.listen()

conn,addr = sk.accept()
print(addr)
dic = {'filename':'黏包.mp4', 'filename_md5':str(md5),
       'filesize':os.path.getsize(r'D:\战狼.rmvb')}
str_dic = json.dumps(dic).encode('gbk')
dic_len = struct.pack('i', len(str_dic))
conn.send(dic_len)
conn.send(str_dic)
with open(r'D:\战狼.rmvb', 'rb') as f:
    content = f.read()
conn.send(content)
conn.close()
sk.close()
#####客户端
import json
import struct
import socket
import hashlib

sk = socket.socket()
sk.connect(('127.0.0.1',9000))

dic_len = sk.recv(4)
dic_len = struct.unpack('i',dic_len)[0]
str_dic = sk.recv(dic_len).decode('gbk')
dic = json.loads(str_dic)

md5 = hashlib.md5()
with open(dic['filename'],'wb') as f:
    while True:
        content = sk.recv(1024)
        f.write(content)
        if not content:break
        md5.update(content)
    md5 = md5.hexdigest()
    print(md5)
    if dic['filename_md5'] == str(md5):
        print('md5校验正确--下载成功')
    else:
        print('文件验证失败')
sk.close()

  

socket 验证客户端的合法性

#server端 
#秘钥 # hashlib # md5 # hashlib.md5('秘钥') import os import socket import hmac secret_key = '老衲洗头用飘柔'.encode('utf-8') # 秘钥 sk = socket.socket() sk.bind(('127.0.0.1',9000)) sk.listen() while True: try: conn,addr = sk.accept() random_bytes = os.urandom(32) # 加密方法 conn.send(random_bytes) obj = hmac.new(key =secret_key,msg =random_bytes) ret = obj.hexdigest() msg = conn.recv(1024).decode('utf-8') if msg == ret:print('是合法的客户端') else:conn.close() finally: sk.close() break
##客户端
import socket
import hmac
secret_key = '老衲洗头用飘柔'.encode('utf-8')
sk = socket.socket()
sk.connect(('127.0.0.1',9000))

urandom = sk.recv(1024)
hmac_obj =  hmac.new(key = secret_key,msg =urandom)
sk.send(hmac_obj.hexdigest().encode('utf-8'))
sk.close()

 

猜你喜欢

转载自www.cnblogs.com/haowen980/p/9010539.html
今日推荐