soketserver是在socket的基础上进行了一层封装,底层还是调用socket,soketserver可以同时实现多个客户端进行通信,多个人可以同时进行上传下载等.
socketserver客户端
# -*- coding:utf-8 -*-
import socket
client = socket.socket()
client.connect((‘127.0.0.1‘,8001))
while 1:
msg = input(‘客户端说>>>‘)
client.send(msg.encode(‘utf-8‘))
from_sesrver_msg = client.recv(1024)
print(from_sesrver_msg.decode(‘utf-8‘))
socketserver服务端
# -*- coding:utf-8 -*-
#引入模块
import socketserver
#自己写一个类,类名自己随便定义,然后继承
class Myserver(socketserver.BaseRequestHandler):
def handle(self): #写一个handle方法,必须叫这个名字
while 1:
from_client_msg = self.request.recv(1024)
print(from_client_msg.decode("utf-8"))
msg = input(‘服务端说:‘)
self.request.send(msg.encode(‘utf-8‘))
if __name__ == ‘__main__‘:
ip_port = (‘127.0.0.1‘,8001)
server = socketserver.ThreadingTCPServer(ip_port,Myserver) #相当于进行bind,listen
server.serve_forever() #使服务器一直开着
在客户端链接增加认证功能,利用hmac+盐的方式来实现
客户端
# -*- coding:utf-8 -*-
from socket import *
import hmac
import os
secret_key = b‘beijing huan ying ni!‘
def conn_auth(conn):
"""
验证客户端到服务器的链接
:param conn:
"""
msg = conn.recv(32)
h = hmac.new(secret_key,msg)
digest = h.digest()
conn.sendall(digest)
def client_handler(ip_port,bufsize=1024):
tcp_socket_client = socket(AF_INET,SOCK_STREAM)
tcp_socket_client.connect(ip_port)
conn_auth(tcp_socket_client)
while 1:
data = input(‘>>:‘).strip()
if not data:continue
if data == ‘quit‘:break
tcp_socket_client.sendall(data.encode(‘utf-8‘))
respone = tcp_socket_client.recv(bufsize)
print(respone.decode(‘utf-8‘))
tcp_socket_client.close()
if __name__ == ‘__main__‘:
ip_port = (‘127.0.0.1‘,9999)
bufsize = 1024
client_handler(ip_port,bufsize)
服务端
# -*- coding:utf-8 -*-
from socket import *
import hmac
import os
secret_key = b‘beijing huan ying ni!‘
def conn_auth(conn):
"""
认证客户端链接
:param conn:
:return:
"""
print(‘开始验证新链接的合法性‘)
msg = os.urandom(32) #生成一个32字节的随机字符串
conn.sendall(msg)
h = hmac.new(secret_key,msg)
digest = h.digest()
respone = conn.recv(len(digest))
return hmac.compare_digest(respone,digest)
def data_handler(conn,bufsize=1024):
if not conn_auth(conn):
print("该链接不合法,关闭")
conn.close()
return
print("链接合法,开始通信")
while 1:
data = conn.recv(bufsize)
if not data:break
conn.sendall(data.upper())
def server_handler(ip_port,bufsize,backlog=5):
"""
只处理链接
:param ip_port:
:param bufsize:
:param backlog:
"""
tcp_socket_server = socket(AF_INET,SOCK_STREAM)
tcp_socket_server.bind(ip_port)
tcp_socket_server.listen(backlog)
while 1:
conn,addr = tcp_socket_server.accept()
print( "新链接[%s:%s]" %(addr[0],addr[1]))
data_handler(conn,bufsize)
if __name__ == ‘__main__‘:
ip_port = (‘127.0.0.1‘,9999)
bufsize = 1024
server_handler(ip_port,bufsize)
os.urandom(n)的使用方法
os.urandom(n)是一种bytes类型的随机生成n个字节字符串的方法,而且每次生成的值不相同.加上md5等加密处理,就能够成内容不同长度相同的字符串
import os
from hashlib import md5
for i in range(10):
print(md5(os.urandom(32)).hexdigest())
import hmac message = b‘Hello world‘ key = b‘secret‘ h = hmac.new(key,message,digestmod=‘MD5‘) print(h.hexdigest()) #比较两个密文是否相同,可以用hmac.compare_digest(密文,密文),返回True或False
hmac和普通hash算法非常相似,hmac输出的长度和原始hash算法长度一致,
注意: 传入的key和message都是bytes类型,str类型需要先编码为bytes
import hmac
import random
def hmac_md5(key,s):
return hmac.new(key.encode(‘utf-8‘),s.encode(‘utf-8‘),‘MD5‘).hexdigest()
class User(object):
def __init__(self,username,password):
self.username = username
self.key = ‘‘.join([chr(random.randint(48,122)) for i in range(20)])
self.password = hmac_md5(self.key,password)
原文:https://www.cnblogs.com/xiaoqianbook/p/10234670.html