Fix a bug that only accept one client to send message

import socket
import threading
import time
from deves import log_output

time_now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
customer = {} #用户存储队列
message_save_list = {} #信息保存队列
#初始化socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
local_addr = ("",8001)
s.bind(local_addr)
s.listen(120)
#设置堵塞状态为否
s.setblocking(False)

def main():
    #启动主线程
    #启动信息保存队列
    t1 = threading.Thread(target=message_save)
    #启动用户接收队列
    t2 = threading.Thread(target=acceptusees)
    #启动信息输出线程
    t3 = threading.Thread(target=out_put_message)
    t1.start()
    t2.start()
    t3.start()

def acceptusees():
    while True:
        #持续接收用户
        socket_info,useraddr = s.accept()
        customer[socket_info] = useraddr
        #创建message_save_list队列初始值,防止报错
        message_save_list[socket_info] = ""
        log_output(message="用户" + useraddr[0] + ":" + str(useraddr[1]) + "进入",level="INFO")

def message_save():
    while True:
        #使用try语句避免解堵塞的时候发生错误
        try:
            for i in list(customer.keys()):
                #进行短暂的时延,模拟堵塞状态,实际为不堵塞状态
                time.sleep(0.1)
                i.setblocking(False)
                try:
                    information = i.recv(1024).decode("utf-8")
                except:
                    continue
                if information == "":
                    #若返回值为空,则证明用户断开连接,删除用户的信息记录
                    leave = customer.pop(i)
                    #删除用户的信息存储
                    message_save_list.pop(i)
                    i.close()
                    print("用户" + leave[0] + ":" + str(leave[1]) + "离开了...")
                else:
                    #将信息加入信息队列等待输出
                        if message_save_list[i] == "":
                            message_save_list[i] = information
                        else:
                            #有多条信息等待输出
                            message_save_list[i] = message_save_list[i] + "|" + information
        #追踪字典更改发生的错误并规避
        except RuntimeError:
            pass

def out_put_message():
    while True:
        #检测用户信息存储数量,若为0则跳过输出
        #循环执行信息输出,输出一个删除一个
        for i in list(message_save_list.keys()):
            #检测信息记录是否为空,若为空则跳过
            if message_save_list.get(i,None) == None:
                continue
            if message_save_list.get(i) == "":
                continue
            #检测是否有多条记录待输出
            if "|" in message_save_list[i]:
                #分割数据进临时数组
                temp_msg_list = message_save_list[i].split("|")
                for msg in temp_msg_list:
                    #对每条信息进行输出
                    log_output("用户 " + customer[i][0] + ":" + str(customer[i][1]) + " 发送信息至服务器:" + " " + msg,level="INFO")
                #清空信息保存
                message_save_list[i] = ""
            else:
                #若无多条信息,则直接输出
                log_output("用户 " + customer[i][0] + ":" + str(customer[i][1]) + " 发送信息至服务器:" + " " + message_save_list[i],level="INFO")
                #清空信息保存
                message_save_list[i] = ""
#调用主线程
if __name__ == '__main__':
    main()


0 条评论

发表回复

头像占位符