电子词典

项目分析


<--!服务器 : 登录  注册   查词   历史记录

客户端 : 打印界面   发出请求    接收反馈   打印结果

技术点 :   并发   sys.fork
           套接字  tcp 套接字
	   数据库  mysql
	   查词    文本

工作流程: 创建数据库,存储数据 ---》 搭建通信框架,            建立并发关系---》实现具体功能封装

1. 创建数据库存储数据
   dict

   user : id  name   passwd
   hist :  id  name   word   time
   words : id  word   interpret

   create database dict default charset=utf8;

   create table user (id int primary key auto_increment,name varchar(32) not null,passwd varchar(16) default '000000');

   create table hist(id int auto_increment primary key,name varchar(32) not null,word varchar(32) not null,time varchar(64));
   
   create table words (id int auto_increment primary key,word varchar(32) not null,interpret text not null);

2. 搭建基本框架
   
   服务器  创建套接字 ---》 创建父子进程 --》 子进程         等待处理客户单端请求--》父进程继续接收下         一个客户端连接

   客户端  创建套接字 --》发起连接请求 --》一级界面         --》请求(登录,注册,退出)--》登录成功         进入二级界面--》请求(查词,历史记录)

3. 功能实现
   注册   
      客户端
         1. 输入注册信息
	 2. 将注册信息发送给服务器
	 3. 得到服务器反馈

      服务端
         1. 接收请求
	 2. 判断是否允许注册
	 3. 将结果反馈给客户端
	 4. 注册信息插入数据库

cookie

 import  getpass
 
 passwd = getpass.getpass()
 功能 : 隐藏密码输入-->

dict_client.py文件

#!/usr/bin/python3 
#coding=utf-8 

from socket import * 
import sys 
import getpass

#创建网络连接
def main():
    if len(sys.argv) < 3:
        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:
                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()
        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()

    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('单词:')
        if word == '##':
            break
        msg = "Q {} {}".format(name,word)
        s.send(msg.encode())
        data = s.recv(128).decode()
        if data == 'OK':
            data = s.recv(2048).decode()
            print(data)
        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()

dict_insert.py文件

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()

dict_server.py文件

'''
name :  Tedu
date :  2018-10-1
email:  xxx
modules: pymongo
This is a dict project 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)

#流程控制
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)
        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]
    passwd = l[2]
    cursor = db.cursor()

    sql = "select * from user \
    where name='%s' and passwd='%s'"%(name,passwd)

    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]
    passwd = 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,passwd) values \
    ('%s','%s')"%(name,passwd)
    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()

    #文本查询
    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'FALL')
            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()
posted @ 2018-11-13 16:10  IndustriousHe  阅读(263)  评论(0编辑  收藏  举报