欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

在线词典

程序员文章站 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()

相关标签: 在线词典