python实现多线程服务端与客户端订票系统

· Special

本文涉及到socket与多线程知识点

# Client端

import socket
import time


# 创建客户端收发

def run():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect(('localhost', 8080))

    print('查询景区票数 / 用户名/地点/订票数量')
    while True:
        #接受用户参数
        user_input = input('请输入查询/预定: ').strip()
        #判断退出
        if user_input.upper() == 'Q':
            print('正在退出')
            time.sleep(0.5)
            break

        #发送配置
        sock.sendall(user_input.encode())

    sock.close()

if __name__ == '__main__':
    run()




Server端

import socket
import time
import datetime
import threading
import os

TICKET_PATH = 'D:\py-project\ticket\db\ticket'
LOG_PATH = 'D:\py-project\log'
lock = threading.RLock()


#验证地点是否存在
def initial():
    scan_list = os.listdir(TICKET_PATH)
    for item in scan_list:
        if not os.path.exists(os.path.join(TICKET_PATH, item)):
            os.mkdir(os.path.join(TICKET_PATH, item))



#搜索
def search(conn,local_name):
    #读取数据并发送
    #拼接路径并判断
    local_path = os.path.join(TICKET_PATH, local_name)
    if not os.path.exists(local_path):
        conn.sendall('地点不存在')
        return

    with open(local_path, 'r') as f:
        data = f.read()
    conn.sendall(data.encode('utf-8'))

#预定
def booking(conn,name,local_name,num):

    lock.acquire()
    #判断地点
    local_path = os.path.join(TICKET_PATH, local_name)
    if not os.path.exists(local_path):
        conn.sendall('地点不存在')
        return
    #判断数量
    ticket_num = int(num)
    if ticket_num < 1:
        conn.sendall('门票数量输入错误')
        return
    with open(local_path, 'r') as f:
        data = int(f.read())
    if data - ticket_num < 0:
        conn.sendall('门票数量不足')
        return

    time.sleep(0.1)
    #写入减去后的数量
    with open(local_path, 'w') as f:
        f.write(str(data - ticket_num))
        conn.sendall('预定成功')


    #写入log
    log_path = os.path.join(LOG_PATH, name)
    with open(log_path, 'a') as f:
        content1 = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        content2 = f'{data - ticket_num}-{content1}-{name}'
        f.write(content2)

    lock.release()



#执行具体接受发送任务
def task(conn):
    #接受传参
    data = conn.recv(1024)
    source_data = data.decode()
    #处理传参
    #判断是查看还是预定
    split_data = source_data.split('-')

    #搜索
    if len(split_data) == 1:
        search(conn,split_data[0])
    #预定
    elif len(split_data) == 3:
        booking(conn,split_data[0],split_data[1],split_data[2])

    else:
        conn.sendall('输入错误,请重试')


#定义多线程
def run():
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(('127.0.0.1', 8080))
    server.listen(5)

    while True:
        client, addr = server.accept()
        thread = threading.Thread(target=task, args=(client,))
        thread.start()
    server.close()

if __name__ == '__main__':
    run()


python


评论

行为验证™ 安全组件加载中...