python (大文件下载及进度条展示) 验证客户端链接的合法性,socketserver

时间:2022-06-29 23:26:21

##########总结###########

文件校验加进度条显示

####server
import os
import json
import socket
import struct
import hashlib sk = socket.socket()
sk.bind(('127.0.0.1', 9000))
sk.listen()
conn, addr = sk.accept()
filename = 'mysql-5.6.42-winx64.zip' # 文件名
absolute_path = os.path.join('D:\老男孩老师笔记\第二阶段共享', filename) # 文件绝对路径
buffer_size = 1024 * 1024 # 缓冲大小,这里表示1MB md5obj = hashlib.md5()
with open(absolute_path, 'rb') as f:
while True:
content = f.read(buffer_size) # 每次读取指定字节
if content:
md5obj.update(content)
else:
break # 当内容为空时,终止循环
md5 = md5obj.hexdigest()#打印出16进制的md5值
print(md5) # 打印md5值 dic = {'filename': filename,
'filename_md5': str(md5), 'buffer_size': buffer_size,
'filesize': os.path.getsize(absolute_path)}
str_dic = json.dumps(dic).encode('utf-8')
len_dic = len(str_dic)
length = struct.pack('i', len_dic)
conn.send(length) # dic的长度
conn.send(str_dic) # dic
with open(absolute_path, 'rb') as f: # 文件
while dic['filesize']:
content = f.read(dic['buffer_size'])
conn.send(content)
dic['filesize'] -= len(content)
'''
这里不能减等4096,因为文件,最后可能只有3字节。
要根据读取的长度len(content),来计算才是合理的。
'''
conn.close()
###############
1cb1926af121c5c1b52a1ec13314805b
####client
import json
import struct
import socket
import sys
import time
import hashlib
import os
def processBar(num, total): # 进度条 [接收大小,文件大小]
rate = num / total
rate_num = int(rate * 100)
if rate_num == 100:
r = '\r%s>%d%%\n' % ('=' * rate_num, rate_num,)
else:
r = '\r%s>%d%%' % ('=' * rate_num, rate_num,)
sys.stdout.write(r)
sys.stdout.flush start_time = time.time() # 开始时间
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('utf-8')
dic = json.loads(str_dic) md5 = hashlib.md5()
with open(dic['filename'], 'wb') as f: # 使用wb更严谨一些,虽然可以使用ab
content_size = 0
while True:
content = sk.recv(dic['buffer_size']) # 接收指定大小
f.write(content) # 写入文件
content_size += len(content) # 接收大小
md5.update(content) # 摘要 processBar(content_size, dic['filesize']) # 执行进度条函数 [接收大小,文件大小]
if content_size == dic['filesize']: break # 当接收的等于文件大小时,终止循环 md5 = md5.hexdigest()
print(md5) # 打印md5值
if dic['filename_md5'] == str(md5):
print(('md5校验正确--下载成功'))
else:
print('文件验证失败')
os.remove(dic['filename']) # 删除文件
sk.close() # 关闭连接
end_time = time.time() # 结束时间
print('本次下载花费了{}秒'.format(end_time - start_time))
############
====================================================================================================>100%
1cb1926af121c5c1b52a1ec13314805b
md5校验正确--下载成功
本次下载花费了18.044031858444214秒

####验证合法性

使用hashlib.md5 加密

python (大文件下载及进度条展示) 验证客户端链接的合法性,socketserver

为什么要随机字符串,是为了防止客户端的数据被窃取

生成随机的bytes类型数据,它是解不出来的

import os
print(os.urandom(32))

执行输出:

b'PO\xca8\xc8\xf3\xa0\xb5,\xdd\xb8K \xa8D\x9cN"\x82\x03\x86g\x18e\xa7\x97\xa77\xb9\xa5VA'

###server
import os
import socket
import hashlib secret_key = '老衲洗头用飘柔' # 加密key sk = socket.socket()
sk.bind(('127.0.0.1',9000))
sk.listen()
while True:
try:
conn,addr = sk.accept()
random_bytes = os.urandom(32) # 随即产生32个字节的字符串,返回bytes
conn.send(random_bytes) # 发送随机加密key
md5 = hashlib.md5(secret_key.encode('utf-8')) # 使用secret_key作为加密盐
md5.update(random_bytes) #得到MD5消息摘要
ret = md5.hexdigest() #以16进制返回消息摘要,它是一个32位长度的字符串
msg = conn.recv(1024).decode('utf-8') # 接收的信息解码
if msg == ret:print('是合法的客户端') # 如果接收的摘要和本机计算的摘要一致,就说明是合法的
else:conn.close() # 关闭连接
finally: # 无论如何,都执行下面的代码
sk.close() # 关闭连接
break
###client
import socket
import hashlib
secret_key = '老衲洗头用飘柔' # 加密key
sk = socket.socket()
sk.connect(('127.0.0.1',9000)) urandom = sk.recv(32) # 接收32字节,也就是os.urandom的返回值
md5_obj = hashlib.md5(secret_key.encode('utf-8')) # 使用加密盐加密
md5_obj.update(urandom)
sk.send(md5_obj.hexdigest().encode('utf-8')) # 发送md5摘要
print('-----')
sk.close() # 关闭连接

先执行server.py,再执行client.py

client输出:-----

server输出:是合法的客户端

socketserver

SocketServer内部使用 IO多路复用 以及 “多线程” 和 “多进程” ,从而实现并发处理多个客户端请求的Socket服务端。即:每个客户端请求连接到服务器时,Socket服务端都会在服务器是创建一个“线程”或者“进 程” 专门负责处理当前客户端的所有请求。

python (大文件下载及进度条展示) 验证客户端链接的合法性,socketserver

它能实现多个客户端,同时连接,它继承了socket

####server
import socketserver
class MyServer(socketserver.BaseRequestHandler):
def handle(self):
print(self.request)
self.request.send(b'hello') # 跟所有的client打招呼
print(self.request.recv(1024)) # 接收客户端的信息 server = socketserver.ThreadingTCPServer(('127.0.0.1',9000),MyServer)
server.serve_forever()
#######client
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',9000))
print(sk.recv(1024))
inp = input('>>>').encode('utf-8')
sk.send(inp)
sk.close()

client输出:

b'hello'
>>>hi

server输出:

<socket.socket fd=316, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 49176)>
b'hi'

开多个客户端,也可以执行

python (大文件下载及进度条展示) 验证客户端链接的合法性,socketserver

python (大文件下载及进度条展示) 验证客户端链接的合法性,socketserver

########自己写一个socketserver

###server
import socket
from threading import Thread
class MySocket:
#init方法,将ip和端口封装到了self里面,并且实例化了一个socket对象
def __init__(self,server_addr): self.server_addr = server_addr
self.socket = socket.socket() #绑定了ip地址和端口,监听,执行了建立连接的方法
def serve_forever(self):
self.socket.bind(self.server_addr)
self.socket.listen(5)
self.build_connect()
#建立连接,将建立连接的过程循环起来,因为我们每次建立连接都需要开一个线程带走这个连接,去通过这个连接收发消息.
def build_connect(self): while 1:
#让主线程代码循环起来,要让accept方法和handle方法要异步起来,不然建立连接的这个循环无法循环起来,因为进入handle之后就出不来了,异步你会想到什么,并发,多进程或者多线程,多进程不合适,所以用多线程,每一个conn,一个线程
conn,addr = self.socket.accept()
# self.handle(conn)
#开线程处理conn,一个线程一个conn,
t = Thread(target=self.handle,args=(conn,))
t.start()
#收发消息的内容,每个线程都需要执行一下handle方法,将conn作为参数传给handle方法
def handle(self,conn):
while 1:
from_client_msg = conn.recv(1024).decode('utf-8')
print('来自客户的消息>>>>',from_client_msg) to_client_msg = input('宝宝说>>>>')
conn.send(to_client_msg.encode('utf-8')) if __name__ == '__main__':
ip_port = ('127.0.0.1',8001)
server = MySocket(ip_port)
server.serve_forever()
###client 可实现多个客户端 同时和一个server应对
import socket
client = socket.socket()
client.connect(('127.0.0.1',8001))
while 1:
to_server_msg = input('给宝宝的消息>>>')
client.send(to_server_msg.encode('utf-8')) from_server_msg = client.recv(1024).decode('utf-8')
print('来自宝宝的消息:',from_server_msg)

python (大文件下载及进度条展示) 验证客户端链接的合法性,socketserver的更多相关文章

  1. python 全栈开发,Day36&lpar;作业讲解&lpar;大文件下载以及进度条展示&rpar;&comma;socket的更多方法介绍&comma;验证客户端链接的合法性hmac&comma;socketserver&rpar;

     先来回顾一下昨天的内容 黏包现象粘包现象的成因 : tcp协议的特点 面向流的 为了保证可靠传输 所以有很多优化的机制 无边界 所有在连接建立的基础上传递的数据之间没有界限 收发消息很有可能不完全相 ...

  2. 036&lowbar;python的大文件下载以及进度条展示

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

  3. Python之socketserver模块和验证客户端链接的合法性

    验证客户端链接的合法性 分布式系统中实现一个简单的客户端链接认证功能 #_*_coding:utf-8_*_ from socket import * import hmac,os secret_ke ...

  4. python&colon;验证客户端链接的合法性与socketserver

    一.验证客户端链接的合法性 from socket import * import hmac,os secret_key=b'linhaifeng bang bang bang' def conn_a ...

  5. python网络编程之验证客户端链接的合法性

    六.socket的更多方法介绍 服务端套接字函数s.bind() 绑定(主机,端口号)到套接字s.listen() 开始TCP监听s.accept() b被动接收TCP客户的连接,(阻塞式)等待连接的 ...

  6. socketv 验证客户端链接的合法性,socketserver

    补充: send()与sendall() 在python socket编程中,有两个发送TCP的函数,send()与sendall(),区别如下: socket.send(string[, flags ...

  7. socketv 验证客户端链接的合法性

    一 .socketv 验证客户端链接的合法性 send()与sendall() 验证客户端 加密验证 如果你想在分布式系统中实现一个简单的客户端链接认证功能,又不像SSL那么复杂,那么利用hmac+加 ...

  8. 一个简单、易用的Python命令行&lpar;terminal&rpar;进度条库

    eprogress 是一个简单.易用的基于Python3的命令行(terminal)进度条库,可以*选择使用单行显示.多行显示进度条或转圈加载方式,也可以混合使用. 示例 单行进度条 多行进度条 圆 ...

  9. Asp&period;Net上传大文件带进度条swfupload

    Asp.Net基于swfupload上传大文件带进度条百分比显示,漂亮大气上档次,大文件无压力,先看效果 一.上传效果图 1.上传前界面:图片不喜欢可以自己换 2.上传中界面:百分比显示 3.上传后返 ...

随机推荐

  1. Linux-ssh配置

  2. Print Common Nodes in Two Binary Search Trees

    Given two Binary Search Trees, find common nodes in them. In other words, find intersection of two B ...

  3. 关于plsql表如何创建自增长列

    1首先在sequence中创建新序列 在oracle中sequence就是所谓的序列号,每次取的时候它会自动增加,一般用在需要按序列号排序的地方. 这是语句创建 create sequence ide ...

  4. 关于对javascript 提升概念 的总结与思考。

    最近在看一本新买的书叫<你不知道的javascript上卷>..买到这本书也算是个巧合 不过真是物有所值.它对js的几个高级概念都做了非常深刻的描述和通过一些通俗易懂的方式来让我们理解.这 ...

  5. 此博客不更新文章,请到www&period;xiaoxiangyucuo&period;com看最新文章

    请到www.xiaoxiangyucuo.com看更多资料,包括Linux,JavaScript,Python,MySQL,PHP,HTML,Photoshop,以及各类软件下载. 希望大家支持,提出 ...

  6. java学习——正则表达式

    本文内容来源于  历经5年锤练--史上最适合初学者入门的Java基础视频 例:要求QQ号长度为5~15位,不能以0开头 String qq="123456"; String reg ...

  7. SQL Server 查看identity值的几种方法。

    方法 1. ident_incr('Table_name');#  增量    identity(A,B) 中的B值 ident_seed('Table_name'); # 种子    identit ...

  8. CloudFoundry 中的GoRouter性能測试

    之前一直感觉CloudFoundry的GoRouter的性能不靠谱,或者我们的CloudFoundry 部署架构存在问题,想着进行一些压力測试,可是一直苦于没有压力測试的工具.上一周,部门须要出一个測 ...

  9. c&plus;&plus;学习笔记—单链表基本操作的实现

    用c++语言实现的单链表基本操作,包括单链表的创建(包括头插法和尾插法建表).结点的查找.删除.排序.打印输出.逆置.链表销毁等基本操作. IDE:vs2013 具体实现代码如下: #include  ...

  10. android安卓生成密钥keystore(命令控制)

    android安卓生成密钥keystore(命令控制) • 配置JDK 详细教程 https://blog.csdn.net/u012934325/article/details/73441617/ ...