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 条评论