Python笔记_28_socket参数_socket的方法_hashlib模块

socket参数的详解

socket.socket(family=AF_INET,type=SOCK_STREAM,proto=0,fileno=None)
创建socket对象的参数说明如下:

参数
family地址系列应为AF_INET(默认值), AF_INET => ipv4
AF_INET6, => ipv6
AF_UNIX,AF_CAN或AF_RDS.(AF_UNIX 域实际上是使用本地 socket [文件]来通信)同一机器
type套接字类型应为SOCK_STREAM(默认值),SOCK_DGRAM,SOCK_RAW或其他SOCK_常量之一。 SOCK_STREAM 是基于TCP的,有保障的(即能保证数据正确传送到对方)面向连接的SOCKET,多用于资料传送。 SOCK_DGRAM 是基于UDP的,无保障的面向消息的socket,多用于在网络上发广播信息。
proto协议号通常为零,可以省略,或者在地址族为AF_CAN的情况下,协议应为CAN_RAW或CAN_BCM之一。
fileno如果指定了fileno,则其他参数将被忽略,导致带有指定文件描述符的套接字返回。 与socket.fromfd()不同,fileno将返回相同的套接字,而不是重复的。 这可能有助于使用socket.close()关闭一个独立的插座。

socket的更多方法介绍(了解)

服务端套接字函数
s.bind() 绑定(主机,端口号)到套接字
s.listen() 开始TCP监听
s.accept() 被动接受TCP客户的连接,(阻塞式)等待连接的到来
客户端套接字函数
s.connect() 主动初始化TCP服务器连接
s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
(等价于:异常处理+connect 一旦网络不通,作用:返回错误号而不是直接报错)
公共用途的套接字函数
s.recv() 接收TCP数据
s.send() 发送TCP数据,send返回值是发送的[字节数量],这个值可能小于要发送的string字节数
s.sendall() 发送TCP数据,sendall返回值是None,发送string所有数据
# 下面两个代码等价:
    #sendall => sock.sendall('Hello world\n')
    #send => buffer = 'Hello world\n'
             while buffer:
        		n = sock.send(buffer)
        		buffer = buffer[n:] (切片)
s.recvfrom() 接收UDP数据
s.sendto() 发送UDP数据
s.getpeername() 连接到当前套接字的远端的地址
s.getsockname() 当前套接字的地址
s.getsockopt() 返回指定套接字的参数
s.setsockopt() 设置指定套接字的参数
s.close() 关闭套接字
面向锁的套接字方法
s.setblocking() 设置套接字的阻塞与非阻塞模式
s.settimeout() 设置阻塞套接字操作的超时时间
s.gettimeout() 得到阻塞套接字操作的超时时间
面向文件的套接字的函数
s.fileno() 套接字的文件描述符
s.makefile() 创建一个与该套接字相关的文件

hashlib模块

hashlib 这个模块是一堆加密算法的集合体,哈希算法的加密方式不止一种
md5解密网站

应用场景:在需要效验功能时使用

  • 用户密码的 => 加密,解密
  • 相关效验的 => 加密,解密

哈希算法也叫摘要算法,相同的数据始终得到相同的输出,不同的数据得到不同的输出。

  • 哈希将不可变的任意长度的数据,变成具有固定长度的唯一值
  • 字典的键值对映射关系是通过哈希计算的,哈希存储的数据是散列(无序)
基本用法
import hashlib

# (1)创建一个md5算法的对象
hs = hashlib.md5()
# (2)把想要加密的字符串通过update更新到hs这个对象
# 参数是二进制字节流
hs.update("wangwendashuaige".encode("utf-8"))
# (3)返回32位16进制的字符串
res = hs.hexdigest()
print(res,len(res))

# 加盐 (加key 只有你自己知道的明文) 目的:增加密码的复杂度
hs = hashlib.md5("Xboyww_".encode("utf-8"))
hs.update("123".encode("utf-8"))
res = hs.hexdigest()
print(res)

# 动态加盐
import random
res = str(random.randrange(10000,100000))
hs = hashlib.md5(res.encode())
hs.update("aabbccdd".encode())
res = hs.hexdigest()
print(res)

"""
# md5 加密效率块 , 通用的加密方法,安全性稍差 位数是32位
# sha 加密效率慢 , 算法相对来说精密,安全性稍高
"""
print("<============================>")
hs = hashlib.sha1()
hs.update("xboyww_123".encode())
res = hs.hexdigest()
# 返回的加密的字符串长度是40位
print(res,len(res))

# 加盐
hs = hashlib.sha1("PPUU".encode())
hs.update("xboyww_123".encode())
res = hs.hexdigest()
print(res)

# sha512
hs = hashlib.sha512()
hs.update("123456".encode())
res = hs.hexdigest()
# 返回的字符春长度是128位
print(res,len(res))


"""
hmac 加密的算法更加不容易破解
"""
import hmac
import os
key = b"123"
msg = b'456'


# hmac里面的new 方法相当于hashlib创建对象和update粘合在一起的操作.
hm = hmac.new(key,msg)
res = hm.hexdigest()
print(res,len(res))


# 随机返回长度为32位的二进制字节流
key = os.urandom(32)
print(key)

hm = hmac.new(key,msg)
res = hm.hexdigest()
print(res,len(res))
文件校验
import hashlib
"""
# 在r模拟下默认read读的是字符,在rb模式默认read读的是字节.
with open("ceshi1.txt",mode="r",encoding="utf-8") as fp:
	res = fp.read(3)
	print(res)

with open("ceshi1.txt",mode="rb") as fp:
	res = fp.read(3)
	print(res)
"""
# (1) 针对于小文件的内容校验
def check_md5(file):
	with open(file,mode="rb") as fp:
		hs = hashlib.md5()
		hs.update(fp.read())
	return hs.hexdigest()
		
print(check_md5("ceshi1.txt"))
print(check_md5("ceshi2.txt"))

# (2) 针对于大文件的内容校验
hs = hashlib.md5()
hs.update("昨天晚上\n下雨了".encode())
res = hs.hexdigest()
print(res) #894c4dd4b1f57472322db524e7b6a47f


# 可以连续update到hs对象进行字节流的拼接
hs = hashlib.md5()
hs.update("昨天晚上\n".encode())
hs.update("下雨了".encode())
res = hs.hexdigest()
print(res)

# 方法一
def check_md5(file):
	hs = hashlib.md5()
	with open(file,mode="rb") as fp:
		while True:
			content = fp.read(1)
			if content:
				hs.update(content)
			else:
				break
		return hs.hexdigest()
print("<===>")
print(check_md5("ceshi1.txt"))
print(check_md5("ceshi2.txt"))

# 方法二
print("<===>")
import os
def check_md5(file):
	hs = hashlib.md5()
	file_size = os.path.getsize(file)
	with open(file,mode="rb") as fp:
		while file_size:
			# read(1) 最多最多读1个,如果文件空了就不读了.
			content = fp.read(1)
			hs.update(content)
			file_size -= len(content)
		return hs.hexdigest()
print(check_md5("ceshi1.txt"))
print(check_md5("ceshi2.txt"))
合法性校验
  • server服务端
# server 服务端 添加访问的权限验证
import socket
import hmac
import os
def auth(conn,secret_key):
	# 随机获取二进制的字节流
	msg = os.urandom(32)
	# print(msg)
	conn.send(msg)
	hm = hmac.new(secret_key,msg)
	res_serve = hm.hexdigest()
	# 接受客户端发给我的字符串
	res_client = conn.recv(1024).decode("utf-8")
	if res_serve == res_client:
		print("合法的链接")
		return True
	else:
		print("不合法的链接")
		return False

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

conn,addr = sk.accept()
secret_key = b"wangwendashuaige"
# 收发数据逻辑.
# ...
if auth(conn,secret_key):
	# 如果返回真,可以接受客户发来的各种请求
	print(conn.recv(1024).decode("utf-8"))


# 四次挥手
conn.close()
# 退还端口
sk.close()
  • client客户端
import socket
import hmac

def auth(sk,key):
	# 接受服务器发过来的随机二进制字节流
	msg = sk.recv(32)
	# print(msg)
	hm = hmac.new(key,msg)
	res = hm.hexdigest()
	# 把加密后的字符串发送给服务器
	sk.send(res.encode())

sk = socket.socket()

key = b"wangwenchaojidashuaige"
sk.connect( ("127.0.0.1",9000) )
auth(sk,key)
sk.send(b"download")
sk.close()

TCP登陆校验
  • server服务端
# ### 服务器登录
import socket
import json
import hashlib

def get_md5_code(usr,pwd):
	hs = hashlib.md5(usr.encode())
	hs.update(pwd.encode())
	return hs.hexdigest()


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

conn,addr = sk.accept()
# 把接受的字节流变成字符串
msg = conn.recv(1024).decode()
# 反序列化字典
dic = json.loads(msg)
# 默认编辑用户不存在
sign = False

with open("userinfo.txt",mode="r",encoding="utf-8") as fp:
	for line in fp:
	# zhangsan:e7a6d0f97db7ea1c4a0c1c137cbf771c
		usr,pwd = line.strip().split(":")
		if usr == dic["username"] and pwd == get_md5_code(dic['username'],dic['password']):
			res = {"code":1}
			res_msg = json.dumps(res).encode()
			conn.send(res_msg)
			# 该用户找到了,存在
			sign = True			
			break

if sign == False:
	res = {"code":0}
	res_msg = json.dumps(res).encode()
	conn.send(res_msg)

conn.close()
sk.close()

  • client客户端
import socket
import hashlib
import json
# 张三 111
# 李四 222
# 王五 333
# 赵柳 444
# 田七 555

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

# 收发数据的逻辑
usr = input("请输入用户名 :")
pwd = input("请输入您的密码 :")
dic = {"username":usr,"password":pwd,"operate":"login"}
# 把字典序列化成字符串
json_dic = json.dumps(dic)
# 把字符串变成字节流
bytes_msg = json_dic.encode("utf-8")
sk.send(bytes_msg)

# 接受服务器的返回值
res_msg = sk.recv(1024).decode()
# 反序列化成字典
dic_code = json.loads(res_msg)
if dic_code['code']:
	print("恭喜你,登录成功")
else:
	print("抱歉,登录失败")

sk.close()
  • userinfo用户信息
  zhangsan:e7a6d0f97db7ea1c4a0c1c137cbf771c     
lisi:c79439cf9abcbd6c6d46e45766a9e64a
wangwu:f77599e7005939d280742dc8eb5db89a
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值