python_登陆验证文件上传下载_socket
client.py
import os
import sys
import json
import struct
import socket
# 下载--接收文件
def download(sk): # 下载
opt_dic = {'operate':'download'}
my_send(sk,opt_dic)
msg = my_recv(sk)
with open(msg['filename'], 'wb') as f:
print('File is downloading...')
while msg['filesize'] > 0:
content = sk.recv(1024)
msg['filesize'] -= len(content)
f.write(content)
print('File download finished...')
# 上传--传送文件
def upload(sk):
opt_dic = {'operate':'upload'}
my_send(sk,opt_dic)
path_list=my_recv(sk)['upload_path']
for index, path in enumerate(path_list,1):
print(index, path)
selected_path = input('请输入目的文件夹的序号:')
uploaded_file = input('请输入本地要上传的文件的全路径:')
filename = os.path.basename(uploaded_file)
filesize = os.path.getsize(uploaded_file)
dic = {'uploaded_path': selected_path, 'filename': filename, 'filesize': filesize}
my_send(sk,dic)
with open(uploaded_file, mode='rb') as f:
print('File is uploading...')
while filesize > 0:
content = f.read(1024)
filesize -= len(content)
sk.send(content)
print('File upload finished')
# 登录
def login(sk):
while True:
usr = input('用户名:').strip()
pwd = input('密 码 :').strip()
dic = {'username': usr, 'password': pwd} # 将用户名和密码放在字典里发过去,而不是单独发送。
my_send(sk, dic)
ret = my_recv(sk)
if ret['operate'] == 'login' and ret['result']:
print('登录成功')
break
else:
print('登录失败')
# 将 sk.recv(num)封装到函数里:
# 1-提高复用度;2-每次都使用 struct防止粘包 3;将 server,client实现某一功能的代码对应起来(如,两边都有 download())
def my_recv(sk): # 接收
msg_len = sk.recv(4)
dic_len = struct.unpack('i', msg_len)[0]
msg = sk.recv(dic_len).decode('utf-8')
msg = json.loads(msg)
return msg
# 将 sk.send(msg)封装到函数里:
# 1-提高复用度;2-每次都使用 struct防止粘包 3;将 server,client实现某一功能的代码对应起来(如,两边都有 download())
def my_send(sk,dic): # 发送 {'username': usr, 'password': pwd} 或者 {'operate':'download'}
str_dic = json.dumps(dic) # 网络通信中 一般使用 json而非 pickle
b_dic = str_dic.encode('utf-8') # 将 json字符串 encode成 字节串
mlen = struct.pack('i', len(b_dic))
sk.send(mlen) # 4个字节 表示字典转成字节之后的长度
sk.send(b_dic) # 具体的字典数据
def exit(sk):
# sys.exit()
global flag
flag = False
opt_dic = {'operate': 'exit'}
my_send(sk,opt_dic)
# sk.close()
if __name__ == '__main__':
sk = socket.socket()
# sk.connect(('192.168.14.109',9012))
sk.connect(('127.0.0.1',9001))
login(sk) # 登录
# 上传\下载
flag=True
while flag:
opt_lst = ['upload','download','exit']
for index,opt in enumerate(opt_lst,1):
print(index,opt)
num = int(input('请选择您要操作的序号 :'))
getattr(sys.modules[__name__],opt_lst[num-1])(sk)
sk.close()
# sk.close()
server.py (socket版)
import os
import sys
import json
import struct
import socket
import hashlib
# 将 conn.send(msg)封装到函数里,1-提高复用度;2-每次都使用 struct防止粘包
def my_send(conn,dic):
str_dic = json.dumps(dic)
b_dic = str_dic.encode('utf-8')
mlen = struct.pack('i', len(b_dic))
conn.send(mlen) # 4个字节 表示字典转成字节之后的长度
conn.send(b_dic) # 具体的字典数据
# download--发送文件
def download(conn):
abs_path = r'C:\Users\12078\PycharmProjects\OldBoy\Day32\登陆验证文件下载_完整版\视频文件源位置\测试视频.mp4'
filename = os.path.basename(abs_path)
filesize = os.path.getsize(abs_path)
dic = {'filename': filename, 'filesize': filesize}
my_send(conn,dic)
with open(abs_path, mode='rb') as f:
while filesize > 0:
content = f.read(1024)
filesize -= len(content)
conn.send(content)
def upload(conn):
upload_path = ['upload_path1', 'upload_path2']
my_send(conn,{'upload_path':upload_path})
file_dic=my_recv(conn)
file_path = upload_path[int(file_dic['uploaded_path']) - 1] + '\\' + file_dic['filename']
with open(file_path, 'wb') as f:
while file_dic['filesize'] > 0:
content = conn.recv(1024)
file_dic['filesize'] -= len(content)
f.write(content)
# 将 conn.recv(num)封装到函数里,1-提高复用度;2-每次都使用 struct防止粘包
def my_recv(conn):
msg_len = conn.recv(4)
dic_len = struct.unpack('i', msg_len)[0]
msg = conn.recv(dic_len).decode('utf-8')
msg = json.loads(msg) # 网网络通信中使用较多的是json而不是pickle
return msg
# 将密码进行加密,使用username作为 salt
def get_md5(username,password):
md5 = hashlib.md5(username.encode('utf-8'))
md5.update(password.encode('utf-8'))
return md5.hexdigest()
# 登录
def login(conn):
flag = True
while flag:
msg = my_recv(conn) # 接收到的是 dic = {'username': usr, 'password': pwd}
with open('userinfo') as f:
for line in f:
name, pwd = line.strip().split('|')
if name == msg['username'] and pwd == get_md5(name, msg['password']):
res, flag = True, False
break
else:
res = False
dic = {'operate': 'login', 'result': res}
my_send(conn, dic) # 将登录结果发送给 client
def exit(conn):
# sys.exit()
# sk.close()
global flag
flag = False
conn.close() # 只断开和客户端的连接,不关闭服务。
if __name__ == '__main__':
sk = socket.socket()
sk.bind(('127.0.0.1',9001))
sk.listen()
while True: # 允许和多个客户端连接(非并行)
conn,_ =sk.accept()
# 有了一个客户端来连接你
login(conn)
flag = True
while flag:
# 接收消息,根据用户的选择进行上传/下载操作
opt_dic = my_recv(conn) # {'operate':'download'} 或 {'operate':'upload'}
if hasattr(sys.modules[__name__],opt_dic['operate']):
getattr(sys.modules[__name__],opt_dic['operate'])(conn)
# conn.close()
sk.close()
server.py(socketserver版)
import os
import sys
import json
import struct
import hashlib
import socketserver
class Myserver(socketserver.BaseRequestHandler):
def handle(self):
conn = self.request
login(conn)
flag = True
while flag: # 不需要更外层的那个 while了,和多个客户端通讯的任务交给了socketserver.
try:
# 接收消息,根据用户的选择进行上传/下载操作
opt_dic = my_recv(conn) # {'operate':'download'} 或 {'operate':'upload'} ,{'operate':'exit'}
if hasattr(sys.modules[__name__], opt_dic['operate']):
getattr(sys.modules[__name__], opt_dic['operate'])(conn)
if opt_dic['operate']=='exit': flag=False # 这样做判断,虽然破坏了 反射的简介,但【只有这样】才能退出连接。
except ConnectionResetError: # 处理异常断开连接,比如客户端非正常退出。
break
conn.close() # 只断开和客户端的连接,不关闭服务。
# 将 conn.send(msg)封装到函数里,1-提高复用度;2-每次都使用 struct防止粘包; 3-每次 send/recv都struct一下。
def my_send(conn,dic):
str_dic = json.dumps(dic)
b_dic = str_dic.encode('utf-8')
mlen = struct.pack('i', len(b_dic))
conn.send(mlen) # 4个字节 表示字典转成字节之后的长度
conn.send(b_dic) # 具体的字典数据
# download--发送文件
def download(conn):
abs_path = r'C:\Users\12078\PycharmProjects\OldBoy\Day32\登陆验证文件下载_完整版\视频文件源位置\测试视频.mp4'
filename = os.path.basename(abs_path)
filesize = os.path.getsize(abs_path)
dic = {'filename': filename, 'filesize': filesize}
my_send(conn,dic)
with open(abs_path, mode='rb') as f:
while filesize > 0:
content = f.read(1024)
filesize -= len(content)
conn.send(content)
def upload(conn):
upload_path = ['upload_path1', 'upload_path2']
my_send(conn,{'upload_path':upload_path})
file_dic=my_recv(conn)
file_path = upload_path[int(file_dic['uploaded_path']) - 1] + '\\' + file_dic['filename']
with open(file_path, 'wb') as f:
while file_dic['filesize'] > 0:
content = conn.recv(1024)
file_dic['filesize'] -= len(content)
f.write(content)
# 将 conn.recv(num)封装到函数里,1-提高复用度;2-每次都使用 struct防止粘包; 3-每次 send/recv都struct一下。
def my_recv(conn):
msg_len = conn.recv(4)
dic_len = struct.unpack('i', msg_len)[0]
msg = conn.recv(dic_len).decode('utf-8')
msg = json.loads(msg) # 网网络通信中使用较多的是json而不是pickle
return msg
# 将密码进行加密,使用username作为 salt
def get_md5(username,password):
md5 = hashlib.md5(username.encode('utf-8'))
md5.update(password.encode('utf-8'))
return md5.hexdigest()
# 登录
def login(conn):
flag = True
while flag:
msg = my_recv(conn) # 接收到的是 dic = {'username': usr, 'password': pwd}
with open('userinfo') as f:
for line in f:
name, pwd = line.strip().split('|')
if name == msg['username'] and pwd == get_md5(name, msg['password']):
res, flag = True, False
break
else:
res = False
dic = {'operate': 'login', 'result': res}
my_send(conn, dic) # 将登录结果发送给 client
def exit(conn):
# sys.exit()
# sk.close()
# global flag
# flag = False
conn.close() # 只断开和客户端的连接,不关闭服务。
if __name__ == '__main__':
flag = True
server = socketserver.ThreadingTCPServer(('127.0.0.1', 9001), Myserver)
server.serve_forever()
python_登陆验证文件上传下载_socket的更多相关文章
- FastDFS实现文件上传下载实战
正好,淘淘商城讲这一块的时候,我又想起来当时老徐让我写过一个关于实现FastDFS实现文件上传下载的使用文档,当时结合我们的ITOO的视频系统和毕业论文系统,整理了一下,有根据网上查到的知识,总结了一 ...
- HttpClient文件上传下载
1 HTTP HTTP 协议可能是如今 Internet 上使用得最多.最重要的协议了,越来越多的 Java 应用程序须要直接通过 HTTP 协议来訪问网络资源. 尽管在 JDK 的 java.net ...
- Java实现FTP批量大文件上传下载篇1
本文介绍了在Java中,如何使用Java现有的可用的库来编写FTP客户端代码,并开发成Applet控件,做成基于Web的批量.大文件的上传下载控件.文章在比较了一系列FTP客户库的基础上,就其中一个比 ...
- Python 基于Python实现Ftp文件上传,下载
基于Python实现Ftp文件上传,下载 by:授客 QQ:1033553122 测试环境: Ftp客户端:Windows平台 Ftp服务器:Linux平台 Python版本:Python 2.7 ...
- django 12天(跨域,文件上传,下载,cookie,session)
django 12天(跨域,文件上传,下载) 跨域 什么是跨域 1.协议不同 2.端口不同 3.主机不同 如何解决跨域 1.安装django-cors-headers模块 2.在settings.py ...
- Django文件上传下载与富文本编辑框
django文件上传下载 上传 配置settings.py # 设定文件的访问路径,如:访问http://127.0.0.1:8000/media/就可以获取文件 MEDIA_URL = '/medi ...
- Struts的文件上传下载
Struts的文件上传下载 1.文件上传 Struts2的文件上传也是使用fileUpload的组件,这个组默认是集合在框架里面的.且是使用拦截器:<interceptor name=" ...
- Android okHttp网络请求之文件上传下载
前言: 前面介绍了基于okHttp的get.post基本使用(http://www.cnblogs.com/whoislcj/p/5526431.html),今天来实现一下基于okHttp的文件上传. ...
- Selenium2学习-039-WebUI自动化实战实例-文件上传下载
通常在 WebUI 自动化测试过程中必然会涉及到文件上传的自动化测试需求,而开发在进行相应的技术实现是不同的,粗略可划分为两类:input标签类(类型为file)和非input标签类(例如:div.a ...
随机推荐
- C++ 构造函数、拷贝构造函数、赋值运算符
<C++ Primer Plus> 12.1 动态内存和类 12.1.1 复习示例和静态类成员 不能在类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但并不分配内存 如果在头文 ...
- 多测师讲解selenium_运行报告相出错归纳_高级讲师肖sir
<_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'> EETraceback (most recent c ...
- composer 阿里云镜像配置
https://developer.aliyun.com/composer 全局配置(推荐) 所有项目都会使用该镜像地址: composer config -g repo.packagist comp ...
- rabbitmq 延时队列
前言 某个产品 或者订单,有个有效期 过了有效期要取消 方法一 : 写个脚本,用crontab 定时扫描 改变状态 但是最低只能一分钟 ,不适合 方法二 : 用swoole得毫秒定时器,每秒钟去扫描表 ...
- go mod模式,引入自己的包,goland飘红
- 阿里技术专家十五问,真题面试刀刀见肉,快来和阿里面试官battle
引言 2020阿里巴巴专家组出题,等你来答: 题目:如何判断两个链表是否相交 出题人:阿里巴巴新零售技术质量部 参考答案: $O(n^2)$: 两层遍历,总能发现是否相交 $O(n)$: 一层遍历,遍 ...
- MVC注册
前言 最近没什么写的,写个MVC注册巩固一下 HTML @{ Layout = null; } <!DOCTYPE html> <html> <head> < ...
- vscode自定义插件安装位置
vscode的插件默认安装位置在: C:\Users\用户名\.vscode\extensions 如果不想将插件安装在C盘,可以自定义一个目标位置存储,使用如下: 右键快捷方式,在原本的目标后加入- ...
- 学python,大概要多久?
都让开!本人文科生,自学Python 2年半,作为一个曾经完全0基础,啥都不懂纯靠自学学会python的文科生,有一些不成熟的小建议可以分享一下. 首先不要觉着编程难,只要你认识26个英文字母,有一点 ...
- JUC之线程池-三大方法-七大参数-四种拒绝策略
线程池:重点 三大方法 七大参数 四种拒绝策略 使用池化技术的理由: 我们的程序伴随着创建销毁线程十分浪费资源, 所以使用线程池,先创建线程,随用随取,用完归还 简单来说就是节约了资源. 使用线程池的 ...