import threading |
import time |
import logging |
import socket |
logging.basicConfig( format = '%(thread)s %(threadName)s %(message)s' ,level = logging.INFO) |
class ChatServer: |
def __init__( self ,ip = '127.0.0.1' ,port = 9999 ): |
self .sock = socket.socket() |
self .addr = (ip,port) |
self .clients = {} |
self .event = threading.Event() |
def start( self ): |
self .sock.bind( self .addr) |
self .sock.listen() |
threading.Thread(target = self ._accept,name = 'accept' ).start() |
def stop( self ): |
for c in self .clients.values(): |
c.close() |
self .sock.close() |
self .event.wait( 3 ) |
self .event. set () |
def _accept( self ): |
while not self .event.is_set(): |
conn,client = self .sock.accept() #阻塞 |
self .clients[client] = conn #ip + port |
threading.Thread(target = self ._recv,args = (conn,client),name = '{}-recv' . format (client)).start() |
def _recv( self ,conn,client): |
#接收到了数据,然后分发 |
while not self .event.is_set(): |
try : |
data = conn.recv( 1024 ) |
except Exception as e: |
logging.info(e) |
data = b "quit" |
data = data.decode() |
logging.info(data) |
#客户端通知,退出机制 |
if data = = "quit" : |
logging.info( '``````quit````' ) |
self .clients.pop(client) |
conn.close() |
break |
msg = 'ack {}' . format (data) |
for conn in self .clients.values(): |
conn.send(msg.encode()) # 发送给客户端消息,data是字节 |
cs = ChatServer() |
cs.start() |
e = threading.Event() |
def showthreads(): |
while not e.wait( 3 ): |
logging.info(threading. enumerate ()) |
threading.Thread(target = showthreads,name = 'showthread' ,daemon = True ).start() |
while True : |
cmd = input ( ">>>" ).strip() |
if cmd = = 'quit' : |
cs.stop() |
break |