day30

作业

#__author : 'liuyang' 
#date : 2019/4/11 0011 下午 12:36
# 这两天 1.软件开发规范  不写 没法做新作业
#2. 认证+上传 +下载 + 校验文件的一致性
# 3. socketserver   实现一个并发的上传
# 4. 选做:    #进度条
# 5.默写 并发的socketserver
# 内置函数  print
import time
for i in range(0,101,2):
     time.sleep(0.1)
     char_num = i//2      #打印多少个'*'
     per_str = '
%s%% : %s
' % (i, '*' * char_num) if i == 100 else '
%s%% : %s'%(i,'*'*char_num)
     print(per_str,end='', flush=True)
#小越越  : 
 可以把光标移动到行首但不换行

# 打印进度条
View Code

sock的其它方法

#__author : 'liuyang' 
#date : 2019/4/11 0011 下午 12:20
# 没来得及 关闭 报错导致 conn.close() 和 sk.close()
    #端口没被占用  其实已经被占用了
# sk.bind(()) # 申请了一个资源  向操作系统
'''
import socket
sk = socket.socket()
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSERADDR,1)
#防止程序因为意外退出之后程序出现端口 被占用的错
        #生产环境上不大用 不允许报错  不能另人占你端口


sk.bind(('127.0.0.1',9001))
sk.listen()
# 其他代码
sk.close()
'''
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',9001))
sk.setblocking(False)    #blocking 阻塞 设置  不设置默认阻塞
            # 非阻塞   #输入什么的没法非阻塞
sk.listen()

conn_l = []
while True:
    try :
        conn,addr = sk.accept()
        # conn.recv()     #也不阻塞了  网络框架都用非阻塞 阻塞效率太低
        conn_l.append(conn)
    except BlockingIOError:
        for conn in conn_l:
            try:
                msg = conn.recv(1024).decode('utf-8')
                print(msg)
                conn.send(msg.upper().encode('utf-8'))
            except BlockingIOError:
                 pass
    # sk.accept()
# 不阻塞 conn1 不说话 去问 conn2  tcp的1对多
server
import socket

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

while True:
    sk.send(b'hello')
    ret = sk.recv(1024)
    print(ret)
client 1 and 2

实现了tcp的一对多  不阻塞 input 不行

import os
import socket
import hmac
secret_key= b'liuyang'
ret = os.urandom(32) #给每一个客户端发送一个随机的字符串,来保证即使数据被拦截你也不能使用这个信息
sk = socket.socket()
sk.bind(('127.0.0.1',9000))
sk.listen()
conn,addr = sk.accept()
conn.send(ret)

hmac = hmac.new(secret_key,os.urandom(32))
print(hmac.digest())
ret  =  conn.recv(1024)

if ret == hmac.digest():
    print('')
else:
    print('不适')
错误的hmac server
#__author : 'liuyang' 
#date : 2019/4/11 0011 下午 12:07
#__author : 'liuyang'
#date : 2019/4/11 0011 下午 12:02
import socket
import hmac
import os
sercet_key = b'liuyang'
sk = socket.socket()
sk.connect(('127.0.0.1',9000))

rand = sk.recv(32)
hmac = hmac.new(sercet_key,os.urandom(32))
print(hmac.digest())
# sk.send(res1.encode('utf-8'))
sk.send(hmac.digest())
# hmac.digest()
sk.close()
client

正确

import os
import hashlib
import socket

secret_key = b'alex sb'
#os.urandom(32) 给每一客户端发送一个随机的字符串,来保证即使数据被拦截你也不能使用这个消息
sk = socket.socket()
sk.bind(('127.0.0.1',9001))
sk.listen()

conn,addr = sk.accept()
rand = os.urandom(32)
conn.send(rand)

sha = hashlib.sha1(secret_key)
sha.update(rand)
res = sha.hexdigest()

ret = conn.recv(1024).decode('utf-8')
if ret == res:
    print('是合法的客户端')
else:
    print('不是合法的客户端')
    conn.close()
server
import socket
import hashlib

secret_key = b'alexsb'
sk = socket.socket()
sk.connect(('127.0.0.1',9001))

rand = sk.recv(32)

sha = hashlib.sha1(secret_key)
sha.update(rand)
res = sha.hexdigest()

sk.send(res.encode('utf-8'))

sk.close()
client

hmac模块

import os
import hmac

hmac = hmac.new(b'alex sb',os.urandom(32))
print(hmac.digest())
自动字节

为什么验证客户端 的合法性

#__author : 'liuyang' 
#date : 2019/4/11 0011 上午 11:20
# http  # 登录博客园  用户名  明文(不安全)或者密文(小网站舍不得花钱)
# https  #发送用户名密码之后 内置特殊加密手段

# 防数据拦截 网安

# import socketserver
# class Manager(socketserver.BaseRequestHandler):
#     def hander(self):
#         conn = self.request
#         print(conn)
# socketserver.ThreadingTCPServer((),Manager)
# socke

# 各个分校  向北京(客户端吗)推送招生信息 每晚12点
# 劫持的人 获得了北京的ip 地址 扫端口
# ip + port(循环或者猜)  别人给你发了不好的信息
# 多个用同一个认真协定  多个登录的话太麻烦

# 不适一个面向用户的,需要用户自己输入用户名和密码的
# 而是面向一台server 的所有的(500台)
# 都是以一种我们共同的方式来进行一个验证

# server 端 密钥key:   客户端知道
        #生成随机的字符串     发给他   gdgadsgas   #通过特殊的算法得到一个结果
        #再生成随机的字符串     发给他  dgadgasdg
        # 密钥+ 随机的字符串 通过特殊的算法得到一个结果  比对
                                            # 密钥+ 随机+特殊算法 难破解
View Code
#__author : 'liuyang'
#date : 2019/4/11 0011 上午 11:55
import os
import hashlib
import socket
secret_key= b'liuyang'
ret = os.urandom(32) #给每一个客户端发送一个随机的字符串,来保证即使数据被拦截你也不能使用这个信息
print(ret)#b'lKx12xb4xabcxd92Q%xd5x05x0fzxf2cgxb8bx0c?xf13xf3x92:x91x00x079xdfx9d'
sk = socket.socket()
sk.bind(('127.0.0.1',9000))
sk.listen()
conn,addr = sk.accept()
conn.send(ret)

sha = hashlib.sha1(secret_key)
sha.update(ret)
res1 = sha.hexdigest()
ret  =  conn.recv(1024).decode('utf-8')

if ret == res1:
    print('')
else:
    print('不适')
md5 版本的 server
#__author : 'liuyang' 
#date : 2019/4/11 0011 下午 12:02
import socket
import hashlib
sercet_key = b'liuyang'
sk = socket.socket()
sk.connect(('127.0.0.1',9000))

rand = sk.recv(32)
sha = hashlib.sha1(sercet_key)
sha.update(rand)
res1 = sha.hexdigest()
sk.send(res1.encode('utf-8'))

sk.close()
View Code

并发

#__author : 'liuyang' 
#date : 2019/4/11 0011 上午 10:40
# while True      conn.close()
# 一个连  另一个不能连
import socketserver     #原生socket(底层)的 上层
                        #socketserver(底层)模块
                        #socketserver网络连接这个操作是socket模块实现的
import time
# 同时接受多个 所有有写了一个 还有太多了
class Myserver(socketserver.BaseRequestHandler):
    def handle(self):   #必须继承这个类 重写方法两个不可改  类名可改
        conn = self.request     #这个就是conn 只要有人连  执行handle
        for i in range(200):
          # print(self.request)
            conn.send(('hello%s'%i).encode('utf-8'))

            msg = conn.recv(1023)
            print(msg)
            time.sleep(0.5)
server = socketserver.ThreadingTCPServer(('127.0.0.1',9001),Myserver) #t现成
server.serve_forever()
'''
server 端给每一个client 提供相同的服务'''

# 实例化 socket  去绑定端口listen       ThreadingTCPServer
# accept        server.serve_forever()   做的

# self.handle()  执行子类的  没有 init 执行init 的 里面有self.handle()
# 没有self.handle1() 所以不能改handle()   #源码里经常遇到
    # 源码很混乱
server
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',9001))

while True:
    msg = sk.recv(1024)
    print(msg)
    sk.send(msg)
sk.close()
client
import socketserver     #原生socket(底层)的 上层
import time
class Myserver(socketserver.BaseRequestHandler):
    def handle(self):   #必须继承这个类 重写方法两个不可改  类名可改
        conn = self.request     #这个就是conn 只要有人连  执行handle
        for i in range(200):
            conn.send(('hello%s'%i).encode('utf-8'))

            msg = conn.recv(1023)
            print(msg)
            time.sleep(0.5)
server = socketserver.ThreadingTCPServer(('127.0.0.1',9001),Myserver) #t现成
server.serve_forever()
View Code
#__author : 'liuyang' 
#date : 2019/4/11 0011 上午 10:48
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',9001))

while True:
    msg = sk.recv(1024)
    print(msg)
    sk.send(msg)
sk.close()
View Code

登录

import json
import struct
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',9001))
sk.listen()
conn,addr = sk.accept()
def shou(conn):
    len_bytes = conn.recv(4)
    num = struct.unpack('i',len_bytes)[0]
    str_dic = conn.recv(num).decode('utf-8')
    dic = json.loads(str_dic)
    print(dic)
    with open(dic['filename'],'wb')as f:
        while dic['filesize']:  #一直减 不为0
            content = conn.recv(2048)   #超过1500 带宽 拆包了
            print(len(content))
            f.write(content)
            dic['filesize'] -= len(content)
shou(conn)
conn.close()
sk.close()
server
import socket
import os
import json
import struct
sk = socket.socket()
sk.connect(('127.0.0.1',9001))
def chuan(sk):
    filepath  = input('请输入文件路径 :')
    filename = os.path.basename(filepath)
    filesize = os.path.getsize(filepath)
    dic = {'filesize':filesize,'filename':filename}
    str_dic = json.dumps(dic)
    bytes_dic = str_dic.encode('utf-8')
    len_bytes = struct.pack('i',len(bytes_dic))
    sk.send(len_bytes)
    sk.send(bytes_dic)
    with open(filepath,'rb') as f:
        while filesize > 2048:
            content = f.read(2048)
            print(len(content))
            sk.send(content)
            filesize -= 2048
        else:       #最后读剩下的 不用判断
            content = f.read()
            sk.send(content)
chuan(sk)
sk.close()
View Code

 teacher

import json
import socket
import struct
import hashlib
def get_md5(usr,pwd):
    md5 = hashlib.md5(usr.encode('utf-8'))
    md5.update(pwd.encode('utf-8'))
    return md5.hexdigest()

def login(conn):
    msg = conn.recv(1024).decode('utf-8')
    dic = json.loads(msg)
    with open('userinfo', encoding='utf-8') as f:
        for line in f:
            username, password = line.strip().split('|')
            if username == dic['user'] and password == get_md5(dic['user'], dic['passwd']):
                res = json.dumps({'flag': True}).encode('utf-8')
                conn.send(res)
                return True
        else:
            res = json.dumps({'flag': False}).encode('utf-8')
            conn.send(res)
            return False

def upload(conn):
    len_bytes = conn.recv(4)
    num = struct.unpack('i', len_bytes)[0]
    str_dic = conn.recv(num).decode('utf-8')
    dic = json.loads(str_dic)

    with open(dic['filename'], 'wb') as f:
        while dic['filesize']:
            content = conn.recv(2048)
            f.write(content)
            dic['filesize'] -= len(content)

sk = socket.socket()
sk.bind(('127.0.0.1',9001))
sk.listen()
while True:
    try:
        conn,addr = sk.accept()
        ret = login(conn)
        if ret:
            upload(conn)
    except Exception as e:
        print(e)
    finally:
        conn.close()
sk.close()
View Code
import os
import json
import socket
import struct

def upload(sk):
    # 上传文件
    file_path = input('>>>')
    filename = os.path.basename(file_path)
    filesize = os.path.getsize(file_path)
    dic = {'filename': filename, 'filesize': filesize}
    bytes_dic = json.dumps(dic).encode('utf-8')

    len_bytes = struct.pack('i', len(bytes_dic))
    sk.send(len_bytes)
    sk.send(bytes_dic)

    with open(file_path, 'rb') as f:
        while filesize > 2048:
            content = f.read(2048)
            sk.send(content)
            filesize -= 2048
        else:
            content = f.read()
            sk.send(content)

usr = input('username :')
pwd = input('password :')
dic = {'operate':'login','user':usr,'passwd':pwd}
bytes_dic = json.dumps(dic).encode('utf-8')
sk = socket.socket()
sk.connect(('127.0.0.1',9001))
sk.send(bytes_dic)

res = sk.recv(1024).decode('utf-8')
dic = json.loads(res)
if dic['flag']:
    print('登录成功')
    upload(sk)
else:
    print('登录失败')

sk.close()
client

 自己

import socket
import os
import json
import struct
sk = socket.socket()
sk.connect(('127.0.0.1',9001))
def chuan(sk):
    filepath  = input('请输入文件路径 :')
    filename = os.path.basename(filepath)
    filesize = os.path.getsize(filepath)
    dic = {'filesize':filesize,'filename':filename}
    str_dic = json.dumps(dic)
    bytes_dic = str_dic.encode('utf-8')
    len_bytes = struct.pack('i',len(bytes_dic))
    sk.send(len_bytes)
    sk.send(bytes_dic)
    with open(filepath,'rb') as f:
        while filesize > 2048:
            content = f.read(2048)
            print(len(content))
            sk.send(content)
            filesize -= 2048
        else:       #最后读剩下的 不用判断
            content = f.read()
            sk.send(content)
    flag = sk.recv(1034).decode('utf-8')
    print(flag)
def login(sk):
    user = input('username:')
    pwd = input('password')
    dic = {'operate':'login','user':user,'pwd':pwd}
    bytes_dic = json.dumps(dic).encode('utf-8')
    sk.send(bytes_dic)
    res = sk.recv(1024).decode('utf-8')
    dic = json.loads(res)
    if dic['flag']:
        print('登录成功')
        return True
        # 文件上传
    else:
        print('登录失败')
        return False
def again_upload(sk):

    # len_bytes = sk.recv(4)
    # num = struct.unpack('i', len_bytes)[0]
    # str_dic = sk.recv(num).decode('utf-8')
    # dic = json.loads(str_dic)
    # print(dic)
    # with open(dic['filename'], 'wb')as f:
    #     while dic['filesize']:  # 一直减 不为0
    #         content = sk.recv(2048)  # 超过1500 带宽 拆包了
    #         print(len(content))
    #         f.write(content)
    #         dic['filesize'] -= len(content)
            # 到最后都发送过来内容 文件大小一直减 到最后为零了
    # sk.close()
    with open('xiazai', 'wb')as f:
        a = sk.recv(100000000)
        f.write(a)
# login(sk)
    # 合起来   不同的功能放在不同的函数里面
    # 判断了 先登录再上传
global xiazai1
if login(sk) :
    chuan(sk)
    print('传输完')
    xiazai1 = True
else:
    print('没传输')

# if flag=='Y':
#     again_upload(sk)
#     print('接受完')
# else:
#     print('没接收完')
sk.close()
# '''
client
#__author : 'liuyang'
#date : 2019/4/11 0011 下午 4:46
#__author : 'liuyang'
#date : 2019/4/11 0011 下午 3:16
# '''
import socket
import os
import json
import struct
sk = socket.socket()
sk.connect(('127.0.0.1',9001))
def chuan(sk):
    filepath  = input('请输入文件路径 :')
    filename = os.path.basename(filepath)
    filesize = os.path.getsize(filepath)
    dic = {'filesize':filesize,'filename':filename}
    str_dic = json.dumps(dic)
    bytes_dic = str_dic.encode('utf-8')
    len_bytes = struct.pack('i',len(bytes_dic))
    sk.send(len_bytes)
    sk.send(bytes_dic)
    with open(filepath,'rb') as f:
        while filesize > 2048:
            content = f.read(2048)
            print(len(content))
            sk.send(content)
            filesize -= 2048
        else:       #最后读剩下的 不用判断
            content = f.read()
            sk.send(content)
    flag = sk.recv(1034).decode('utf-8')
    print(flag)
def login(sk):
    user = input('username:')
    pwd = input('password')
    dic = {'operate':'login','user':user,'pwd':pwd}
    bytes_dic = json.dumps(dic).encode('utf-8')
    sk.send(bytes_dic)
    res = sk.recv(1024).decode('utf-8')
    dic = json.loads(res)
    if dic['flag']:
        print('登录成功')
        return True
        # 文件上传
    else:
        print('登录失败')
        return False
def again_upload(sk):

    # len_bytes = sk.recv(4)
    # num = struct.unpack('i', len_bytes)[0]
    # str_dic = sk.recv(num).decode('utf-8')
    # dic = json.loads(str_dic)
    # print(dic)
    # with open(dic['filename'], 'wb')as f:
    #     while dic['filesize']:  # 一直减 不为0
    #         content = sk.recv(2048)  # 超过1500 带宽 拆包了
    #         print(len(content))
    #         f.write(content)
    #         dic['filesize'] -= len(content)
            # 到最后都发送过来内容 文件大小一直减 到最后为零了
    # sk.close()
    with open('xiazai', 'wb')as f:
        a = sk.recv(100000000)
        f.write(a)
# login(sk)
    # 合起来   不同的功能放在不同的函数里面
    # 判断了 先登录再上传
global xiazai1
if login(sk) :
    chuan(sk)
    print('传输完')
    xiazai1 = True
else:
    print('没传输')

# if flag=='Y':
#     again_upload(sk)
#     print('接受完')
# else:
#     print('没接收完')
sk.close()
# '''
server
原文地址:https://www.cnblogs.com/Doner/p/10688978.html