功能说明 :
1.用户能够登录注册
登录:凭借用户名和密码即可
注册:要求用户名和密码 要求用户名不能重复
2. 用户信息需要长期保存
使用mysql 或者 mongo
3. 要求能够满足多用户同时登录操作的情况
4. 用户开启客户端即进入一级界面(登录 注册 退出)
5. 用户登录后即进入二级界面,(查词 查看历史记录 退出界面)
退出 : 退到上一级界面
6.查词:英英词典,可以循环查询,查一个词会反馈给客户端词义
文本操作
将单词本中的单词存在数据库中
7.查看历史记录:查看当前用户的历史查词情况
user word time
8.单词本特征:单词词义从单词本获取
* 每个单词占一行
* 单词和解释之间有空格
* 单词按顺序排列
* 后面的单词比前面的大
提示 :
结构: c/s结构
服务器 : 数据库交互 注册 登录 查词 历史记录 并发(多进程)
客户端 : 打印命令选择界面 提出请求 接收服务端信息 展示内容
技术点 : 并发fork 数据库操作 数据表建立 网络传输TCP
需要模块 : socket pymysql os
1. 确定数据表结构
2. 考虑如何处理单词本(文本,数据库)
3. 确定项目的整体结构
4. 完成整体结构的框架代码
socket --》 tcp
并发 --》 多进程
数据库 --》 mysql
数据库表 user hist words
dict
user : id name passwd
hist : id word time user_id
id name word time
words : id word interpret
服务端:
main():创建套接字--->父子进程--->父进程等待其他客户端连接accept
child():子进程等待接受请求 根据请求调用功能函数 quit()
login():操作数据库比对用户密码 回复结果
register():判断是否和其他用户重名,插入数据库
query():查询数据库将结果给客户端 插入历史记录
history():查询数据库 将结果给客户端
客户端 :
main() : 创建套接字 发送链接请求 ---》一级界面
input ---》发送请求
login() 登录 ---》进入二级界面
register() 注册
query() 发送请求 接受反馈 打印
history() 发送请求 接受反馈 打印
#先将字典的内容导入数据库,当然也可以存为一个文件,这里使用MySQL数据库
import pymysql
import ref = open('dict.txt')
db = pymysql.connect('localhost','root','123456','dict')
cursor = db.cursor()
for line in f:
l = re.split(r'[ ]+',line)
word = l[0]
interpret = ' '.join(l[1:])
sql = "insert into words (word,interpret) values ('%s','%s')"%(word,interpret)
try:
cursor.execute(sql)
db.commit()
except:
db.rollback()
cursor.close()
db.close()
f.close()
#编写在线词典服务端代码
from socket import *
import os,signal,sys,time,pymysql
class dict_server(object):
def __init__(self,c):
self.c = c
#处理客户端的注册请求
def dic_login(self):
self.c.send(b'ok')
data = self.c.recv(1024).decode()
l = data.split("#")
db = pymysql.connect('localhost','root','123456','dict')
cursor = db.cursor()
sql = "select * from user where name = '%s'" % l[0]
vb = cursor.execute(sql)
if vb == 0:
try:
sql = "insert into user (name,passwd) values ('%s','%s')"%(l[0],l[1])
cursor.execute(sql)
db.commit()
except:
db.rollback()
cursor.close()
db.close()
self.c.send(b'ok')
else:
self.c.send(b'no')
#处理客户端的登录请求
def dic_entry(self):
data = self.c.recv(1024).decode()
l = data.split("#")
db = pymysql.connect('localhost','root','123456','dict')
cursor = db.cursor()
sql = "select name from user where name = '%s' and passwd = '%s'" % (l[0],l[1])
vb = cursor.execute(sql)
if vb == 0:
self.c.send(b'no')
else:
self.c.send(b'ok')
#处理客户端的查询请求
def dic_check(self):
self.c.send(b'ok')
db = pymysql.connect('localhost','root','123456','dict')
while True:
data = self.c.recv(1024).decode()
l = data.split("#")
cursor = db.cursor()
sql = "select interpret from words where word = '%s'" % l[1]
vb = cursor.execute(sql)
if vb == 0:
self.c.send(b'no')
else:
self.c.send(cursor.fetchone()[0].encode())
cursor.close()
cursor = db.cursor()
sql = "insert into hist (name,word,time) values ('%s','%s','%s')"%(l[0],l[1],l[2])
cursor.execute(sql)
db.commit()
#查看该用户的查询记录
def dic_history(self):
self.c.send(b'ok')
data = self.c.recv(1024).decode()
db = pymysql.connect('localhost','root','123456','dict')
cursor = db.cursor()
sql = "select word,time from hist where name = '%s'" % data
cursor.execute(sql)
r = cursor.fetchall()
hist_word = ''
for i in r:
hist_word = hist_word + i[0] + ' ' + i[1] +"#"
self.c.send(hist_word.encode())
#设置监听套接字对象
def main():
HOST = '0.0.0.0'
PORT = 8888
ADDR = (HOST,PORT)
s = socket()
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind(ADDR)
s.listen(10)
signal.signal(signal.SIGCHLD,signal.SIG_IGN)
print("监听端口:8888")
#循环接受客户端的连接请求
while True:
try:
c,addr = s.accept()
except KeyboardInterrupt:
s.close()
sys.exit("连接失败,服务器退出")
except Exception as e:
print(e)
continue
print("和",addr,"连接成功")
#创建进程
pid = os.fork()
if pid < 0:
print("创建进程失败")
continue
#子进程处理客户端的具体请求,同时关闭本次的S
elif pid == 0:
s.close()
dic = dict_server(c)
#反复接收客户端的请求,用不同的函数来处理各个请求
while True:
data = c.recv(1024).decode()
if not data:
continue
elif data == "1":
dic.dic_login()
elif data == '2':
dic.dic_entry()
elif data == 'c1':
dic.dic_check()
elif data == 'H':
dic.dic_history()
#父进程继续处理其它客户端的连接请求,同时关闭本次套接字的C
else:
c.close()
continue
if __name__ == '__main__':
main()
#编写在线词典客户端代码
from socket import *
import sys,time
class dict_client(object):
def __init__(self,s):
self.s = s
def do_login(self):
self.s.send(b'1')
data = self.s.recv(1024).decode()
if data == 'ok':
message = ""
login_name = input("请输入注册用户名:")
message = message + login_name +"#"
login_passwd = input("请输入登录密码:")
message = message + login_passwd
self.s.send(message.encode())
data = self.s.recv(1024).decode()
if data == 'ok':
print("注册成功")
else:
print("注册失败,用户名已存在")
return
else:
return
def do_entry(self):
self.s.send(b'2')
msg = ''
entry_name = input("请输入登录用户名:")
msg = msg + entry_name + "#"
entry_passwd = input("请输入登录密码:")
msg = msg + entry_passwd
self.s.send(msg.encode())
data = self.s.recv(1024).decode()
if data == 'no':
print("用户名或密码错误,请重新登录!")
return
elif data == 'ok':
print("登录成功,欢迎%s" % entry_name)
time.sleep(1)
while True:
print("======================")
print("| 1.查词 |")
print("| 2.查看查词记录 |")
print("| 3.退出 |")
print("======================")
cmd = input("请选择:")
if cmd.strip() == '1':
self.do_check(entry_name)
elif cmd.strip() == '2':
self.do_history(entry_name)
elif cmd.strip() == '3':
return
def do_check(self,entry_name):
self.s.send(b'c1')
data = self.s.recv(1024).decode()
if data == 'ok':
while True:
msg = ''
print("##退出")
n = input("请输入单词:")
if n == '##':
return
t = time.ctime()
msg = msg + entry_name + "#" + n + "#" + t
self.s.send(msg.encode())
data = self.s.recv(1024).decode()
if data == 'no':
print("您查询的单词不存在,请重新输入")
continue
else:
print(n,":",data)
def do_history(self,entry_name):
self.s.send(b'H')
data = self.s.recv(1024).decode()
if data == 'ok':
self.s.send(entry_name.encode())
data = self.s.recv(4096).decode()
l = data.split("#")
print("============历史记录==============")
for i in l:
print(i)
def main():
if len(sys.argv) < 3:
print("argv is error")
return
HOST = sys.argv[1]
PORT = int(sys.argv[2])
ADDR = (HOST,PORT)
s = socket()
s.connect(ADDR)
dic = dict_client(s)
while True:
print("====welcome=====")
print("| 1.注册 |")
print("| 2.登录 |")
print("| 3.退出 |")
print("================")
cmd = input("请选择:")
if not cmd:
continue
elif cmd.strip() == '1':
dic.do_login()
elif cmd.strip() == '2':
dic.do_entry()
elif cmd.strip() == '3':
sys.exit("谢谢使用!")
else:
print("指令有误,请重新输入")
continue
if __name__ == '__main__':
main()