在线词典
程序员文章站
2022-03-02 20:55:26
...
在线词典
参考代码: day18/dict
功能说明
用户可以登录和注册
- 登录凭借用户名和密码登录
- 注册要求用户必须填写用户名,密码,其他内容自定
- 用户名要求不能重复
- 要求用户信息能够长期保存
可以通过基本的图形界面print以提示客户端输入。
- 程序分为服务端和客户端两部分
- 客户端通过print打印简单界面输入命令发起请求
- 服务端主要负责逻辑数据处理
- 启动服务端后应该能满足多个客户端同时操作
客户端启动后即进入一级界面,包含如下功能:登录 注册 退出
- 退出后即退出该软件
- 登录成功即进入二级界面,失败回到一级界面
- 注册成功可以回到一级界面继续登录,也可以直接用注册用户进入二级界面
用户登录后进入二级界面,功能如下:查单词 历史记录 注销
- 选择注销则回到一级界面
- 查单词:循环输入单词,得到单词解释,输入特殊符号退出单词查询状态
- 历史记录:查询当前用户的查词记录,要求记录包含name word time。可以查看所有记录或者前10条均可。
客户端
"""
dict 服务端
功能 : 业务逻辑
模型 : 多进程tcp并发
"""
from socket import *
from multiprocessing import Process
import sys,signal
from dict_db import Database
# 全局变量
HOST = '0.0.0.0'
PORT = 8888
ADDR = (HOST,PORT)
# 数据库链接对象
db = Database(user='root',passwd='123456',database='dict')
# 处理注册
def do_register(connfd,name,passwd):
if db.register(name,passwd):
connfd.send(b'OK')
else:
connfd.send(b'FAIL')
# 处理登录
def do_login(connfd,name,passwd):
if db.login(name,passwd):
connfd.send(b'OK')
else:
connfd.send(b'FAIL')
# 查询单词
def do_query(connfd,name,word):
mean = db.query(word) # 负责查询单词
# 查不到返回一个空
if mean:
msg = "%s : %s"%(word,mean)
connfd.send(msg.encode())
db.insert_history(name, word) # 插入历史记录
else:
connfd.send("没有找到该单词".encode())
# 接收请求,调用具体功能函数处理
def request(connfd):
db.create_cursor()
while True:
data = connfd.recv(1024).decode()
tmp = data.split(' ')
if not data or tmp[0] == 'E':
return
elif tmp[0] == 'R':
# R name passwd
do_register(connfd,tmp[1],tmp[2])
elif tmp[0] == 'L':
# L name passwd
do_login(connfd,tmp[1],tmp[2])
elif tmp[0] == 'Q':
# Q name word
do_query(connfd,tmp[1],tmp[2])
def main():
# 创建tcp套接字
s = socket()
s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
s.bind(ADDR)
s.listen(3)
signal.signal(signal.SIGCHLD, signal.SIG_IGN)
print("Listen the port 8888...")
# 循环接收客户端链接
while True:
try:
c, addr = s.accept()
print("Connect from", addr)
except KeyboardInterrupt:
db.close()
sys.exit('服务器退出')
except Exception as e:
print(e)
continue
# 创建进程处理
p = Process(target=request, args=(c,))
p.daemon = True # 父程退出其他线程也退出
p.start()
if __name__ == '__main__':
main()
服务端
在这里插入代码片"""
dict 客户端
功能: 根据用户输入,发送请求,得到结果,展示结果
"""
from socket import *
import sys
from getpass import getpass
# 服务器地址
ADDR = ('127.0.0.1',8888)
# 几乎所有函数都要使用s --》全局变量
s = socket()
try:
s.connect(ADDR)
except:
sys.exit()
# 查单词
def do_query(name):
while True:
word = input("单词:")
if word == '##':
break
msg = "Q %s %s"%(name,word)
s.send(msg.encode())
# 接收结果
data = s.recv(2048).decode()
print(data)
def login(name):
while True:
print("""
==============Query==============
1. 查单词 2. 历史记录 3. 注销
=================================
""")
cmd = input("输入选项:")
if cmd == '1':
do_query(name)
elif cmd == '2':
pass
elif cmd == '3':
return
else:
print("请输入正确选项")
# 处理注册
def do_register():
while True:
name = input("User:")
passwd = getpass()
passwd_ = getpass("Again:")
if passwd != passwd_:
print("两次密码不一致!")
continue
if (' ' in name) or (' ' in passwd):
print("用户名密码请不要加入空格")
continue
msg = "R %s %s"%(name,passwd)
s.send(msg.encode()) # 发送请求
data = s.recv(128).decode() # 收到结果
if data == 'OK':
print("注册成功")
else:
print("注册失败")
return
# 处理登录
def do_login():
name = input("User:")
passwd = getpass()
msg = "L %s %s" % (name, passwd)
s.send(msg.encode()) # 发送请求
data = s.recv(128).decode() # 收到结果
if data == 'OK':
print("登录成功")
login(name)
else:
print("登录失败")
# 程序启动函数
def main():
while True:
print("""
============Welcome============
1. 注册 2. 登录 3. 退出
===============================
""")
cmd = input("输入选项:")
if cmd == '1':
do_register()
elif cmd == '2':
do_login()
elif cmd == '3':
s.send(b'E')
sys.exit("谢谢使用")
else:
print("请输入正确选项")
if __name__ == '__main__':
main()
数据库
"""
dict 数据库处理功能
给server提供所有数据支持
"""
import pymysql
import hashlib
# 加密函数
def change_passwd(passwd):
# 生产hash对象
hash = hashlib.md5("*#06#".encode()) # 加盐生产对象
# 对密码进行加密
hash.update(passwd.encode())
# 提取加密后的密码
return hash.hexdigest()
class Database:
def __init__(self,host='localhost',
port = 3306,
user=None,
passwd=None,
database=None,
charset='utf8'):
self.host = host
self.port = port
self.user = user
self.passwd = passwd
self.database = database
self.charset = charset
self.connect_db() # 链接数据库
def connect_db(self):
self.db=pymysql.connect(host=self.host,
port=self.port,
user=self.user,
passwd=self.passwd,
database=self.database,
charset=self.charset)
# 创建游标
def create_cursor(self):
self.cur = self.db.cursor()
# 关闭数据库
def close(self):
# 如果有 cur这个属性则执行关闭
if hasattr(self,'cur'):
self.cur.close()
if hasattr(self,'db'):
self.db.close()
# 处理注册
def register(self,name,passwd):
# 判断名是否重复
sql = "select name from user where name='%s'" % name
self.cur.execute(sql)
result = self.cur.fetchone() # 查不到返回None
if result:
return False
try:
# 密码转换
passwd = change_passwd(passwd)
sql = "insert into user (name,passwd) values (%s,%s);"
self.cur.execute(sql, [name, passwd])
self.db.commit()
return True
except:
self.db.rollback()
return False
# 处理登录
def login(self,name,passwd):
passwd = change_passwd(passwd)
sql = "select name from user " \
"where name=%s and passwd=%s;"
self.cur.execute(sql, [name, passwd])
result = self.cur.fetchone() # 如果查到说明用户存在
if result:
return True
else:
return False
# 查询单词
def query(self,word):
sql = "select mean from words where word='%s'"%word
self.cur.execute(sql)
r = self.cur.fetchone() # (xxxxx) / None
if r:
return r[0]
# 插入历史
def insert_history(self,name,word):
sql = "select id from user where name='%s'"%name
self.cur.execute(sql)
uid = self.cur.fetchone()[0]
"select id from words where word='%s'"%word
sql = "insert into user_words (uid,wid) values (%s,%s)"
try:
self.cur.execute(sql,[uid,wid])
self.db.commit()
except:
self.db.rollback()
if __name__ == '__main__':
my_db = Database(user='root',passwd='123456',database='stu')
my_db.close()
上一篇: 关于读取jar包中文件的问题