电子词典的项目功能:
第一个项目:电子词典
功能说明:
2.用户数据要求使用数据库长期保存(MYSQL)
数据表自定义,可以存储中文
3.能够满足多个用户同时登录操作的需求(多进程多线程,并发机制)
4.功能分为客户端和服务端,客户端主要发起请求,服务端处理请求,用户启动客户端即进入一级界面
登录 注册 退出
5.用户登录后即进入二级界面
查单词 查看那历史记录 退出
查单词:通过单词本,每行一个单词,单词和解释之间一定有空格
后面的单词一定比前面的大
查单词:输入单词,显示单词意思,可以循环查询。输入##表示退出查词
查看历史记录:查看当前用户的历史查词记录
name word time
退出:退出到一级界面,相当于注销
1.确定技术点:
什么并发,什么套接字,什么数据库? 文件处理还是数据库查询?
如果是数据库查询如何就爱那个单词存入数据库
2.建立数据表
建立几个表 每个表结构 表关系
3 用户信息 历史记录 存单词
功能: 注册 查询历史信息 查单词
登录 查单词
3.项目分析 仿照ftp和聊天室进行项目分析
服务器:登录 注册 查询 历史纪录
客户端:打印界面 发出请求 接收反馈 打印结果
技术点:并发 sys.fork
套接字 tcp套接字
数据库 mysql
查词 文本
首先我们需要将单词库导入到数据库中:
a indef art one
abacus n.frame with beads that slide along parallel rods, used for teaching numbers to children, and (in some countries) for counting
abandon v. go away from (a person or thing or place) not intending to return; forsake; desert
abandonment n. abandoning
abase v. ~ oneself/sb lower oneself/sb in dignity; degrade oneself/sb ;
abash to destroy the self-possession or self-confidence of:disconcert
abashed adj. ~ embarrassed; ashamed
abate v. make or become less
abattoir n. = slaughterhouse (slaughter)
abbess n. woman who is head of a convent or nunnery
abbey n. buildingin which monks or nuns live as a community under an abbot or abbess
abbot n. man who is head of a monastery or abbey
abbreviate v. ~ sth shorten (a word, phrase, etc), esp by omitting letters
abbreviation n. abbreviating or being abbreviated
导入数据库的代码是:
import pymysql
import re
f=open(‘dict.txt’)
db=pymysql.connect(‘localhost’,‘root’,‘123456’,‘dict’)
cursor=db.cursor()
for line in f:
l=re.split(r’\s+’,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()
f.close()
服务端代码:
‘’’
name: Tedu
date: 2018-10-1
email: xxx
modules: pymongo
This is a dict porject for AID
‘’’
from socket import *
import os
import time
import signal
import pymysql
import sys
#定义需要的全局变量
DICT_TEXT=’./dict.txt’
HOST=‘0.0.0.0’
PORT=8000
ADDR=(HOST,PORT)
#TCP并发模型
#主要的流程
def main():
#创建数据库连接
db=pymysql.connect(‘localhost’,‘root’,‘123456’,‘dict’)
#创建套接字
s=socket()
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind(ADDR)
s.listen(5)
#忽略子进程信息号
signal.signal(signal.SIGCHLD,signal.SIG_IGN)
while True:
try:
c,addr=s.accept()
print("Connect from",addr)
except KeyboardInterrupt:
s.close()
sys.exit('服务器退出')
except Exception as e:
print(e)
continue
#创建子进程
pid = os.fork()
if pid == 0:
s.close()
do_child(c,db)#不会产生冲突,自带锁
print('子进程准备处理请求')
sys.exit(0)
else:
c.close()
continue
def do_child(c,db):
#循环接收客户端请求
while True:
data=c.recv(128).decode()
print(c.getpeername(),’:’,data)
if (not data) or data[0]==‘E’:
c.close()
sys.exit(0)
elif data[0]=='R':
do_register(c,db,data)
elif data[0]=='L':
do_login(c,db,data)
elif data[0]=='Q':
do_query(c,db,data)
elif data[0]=='H':
do_hist(c,db,data)
#登录
def do_login(c,db,data):
print(“登录操作”)
l=data.split(’ ')
name=l[1]
password=l[2]
cursor=db.cursor()
sql="select * from user where name='%s' and password='%s'"\
%(name,password)
cursor.execute(sql)
r = cursor.fetchone()
if r == None:
c.send(b'FALL')
else:
print('%s登录成功'%name)
c.send(b'OK')
#注册
def do_register(c,db,data):
print(“注册操作”)
l=data.split(’ ')
name=l[1]
password=l[2]
cursor=db.cursor()
sql="select * from user where name='%s'"%name
cursor.execute(sql)
r = cursor.fetchone()
if r!=None:
c.send(b'EXISTS')
return
#用户不存在的情况下插入用户
sql="insert into user (name,password) values\
('%s','%s')"%(name,password)
try:
cursor.execute(sql)
db.commit()
c.send(b'OK')
except:
db.rollback()
c.send(b'FALL')
else:
print('%s注册成功'%name)
#查询单词
def do_query(c,db,data):
print(“查询操作”)
l=data.split(’ ')
name=l[1]
word=l[2]
cursor=db.cursor()
def insert_history():
tm = time.ctime()
sql="insert into hist(name,word,time)\
values('%s','%s','%s')"%(name,word,tm)
try:
cursor.execute(sql)
db.commit()
except:
db.rollback()
#数据库查询
# sql="select interpret from words where word='%s'"\
# %(word)
# cursor.execute(sql)
# r = cursor.fetchone()
# if r == None:
# c.send(b'select error')
# else:
# print('%s查找成功'%name)
# c.send(r[0].encode())
#文本查询
try:
f=open(DICT_TEXT)
except:
c.send(b'FALL')
return
for line in f:
tmp = line.split(' ')[0]
if tmp > word:
c.send(b'F')
f.close()
return
elif tmp==word:
c.send(b'OK')
time.sleep(0.1)
c.send(line.encode())
f.close()
#查询成功时再插入历史记录
insert_history()
return
c.send(b'FALL')
f.close()
def do_hist(c,db,data):
print(‘历史记录’)
l=data.split(’ ')
name=l[1]
cursor=db.cursor()
sql="select * from hist where name='%s'"%name
cursor.execute(sql)
r=cursor.fetchall()
if not r:
c.send(b'FALL')
return
else:
c.send(b'OK')
for i in r:
time.sleep(0.1)
msg="%s %s %s"%(i[1],i[2],i[3])
c.send(msg.encode())
time.sleep(0.1)
c.send(b'##')
if name == ‘main’:
main()
客户端代码:
#!/usr/bin/python3
#coding=utf-8
from socket import *
import sys
import getpass
#创建网络连接
def main():
if len(sys.argv)❤️:
print(‘argv is error’)
return
HOST = sys.argv[1]
PORT= int(sys.argv[2])
s=socket()
try:
s.connect((HOST,PORT))
except Exception as e:
print(e)
return
while True:
print('''
===============welcome===============
--- 1.注册 2.登录 3.退出---
=====================================
''')
try:
cmd = int(input("输入选项>>"))
except Exception as e:
print('命令错误')
continue
if cmd not in [1,2,3]:
print('请输入正确选项')
sys.stdin.flush()#清除标准输入(清除缓冲区)
continue
elif cmd==1:
r = do_register(s)
if r==0:
print('注册成功')
#login(s,name) #进入二级界面
elif r==1:
print('用户名存在请重新注册')
else:
print('注册失败')
elif cmd==2:
name=do_login(s)
if name:#不为NONE
print('登录成功进入二级界面')
login(s,name)
else:
print('用户名或者密码错误')
elif cmd==3:
s.send(b'E')
sys.exit('谢谢使用')
def do_register(s):
while True:
name = input(‘User:’)
passwd = getpass.getpass()
passwd1 = getpass.getpass(‘Again:’)
if (' ' in name) or (' ' in passwd):
print('用户名或密码不许有空格')
continue
if passwd != passwd1:
print('两次密码不一致')
continue
msg='R {} {}'.format(name,passwd)
#发送请求
s.send(msg.encode())
#等待回复
data=s.recv(128).decode()
print(data)
if data=='OK':
return 0
elif data=='EXISTS':
return 1
else:
return 2
def do_login(s):
name = input(‘User:’)
passwd = getpass.getpass()
msg=‘L {} {}’.format(name,passwd)
#发送请求
s.send(msg.encode())
#等待回复
data=s.recv(128).decode()
print(data)
if data=='OK':
return name
else:
return
#二级页面
def login(s,name):
while True:
print(’’’
=查询界面==
1.查词 2.历史记录 3.退出
==============================
‘’’)
try:
cmd = int(input("输入选项>>"))
except Exception as e:
print('命令错误')
continue
if cmd not in [1,2,3]:
print('请输入正确选项')
sys.stdin.flush()#清除标准输入(清除缓冲区)
continue
elif cmd==1:
do_query(s,name)
elif cmd==2:
do_hist(s,name)
elif cmd==3:
return
def do_query(s,name):
while True:
word = input(‘Word:’)
if word==’##’:
break
msg=‘Q {} {}’.format(name,word)
#发送请求
s.send(msg.encode())
#等待回复
data=s.recv(128).decode()
if data ==‘OK’:
data1=s.recv(2048).decode()
print(data1)
else:
print(‘没有查到该单词’)
def do_hist(s,name):
msg=‘H {}’.format(name)
s.send(msg.encode())
data=s.recv(128).decode()
if data==‘OK’:
while True:
data=s.recv(1024).decode()
if data==’##’:
break
print(data)
else:
print(‘没有历史记录’)
if name == ‘main’:
main()