天天看点

实用:python网络开发中多人聊天室的实现(socketserver)

import socketserver
import threading

#启动服务
class Myhandler(socketserver.BaseRequestHandler):

    def setup(self):
        super().setup()
        self.event = threading.Event()

    def handle(self):
        super().handle()
        print(self.server,self.client_address,self.request)

        while not self.event.wait(1):
            data = self.request.recv(1024)
            msg = 'Your msg = {}'.format(data.decode()).encode()
            print(msg)
            self.request.send(msg)

    def finish(self):
        super().finish()
        self.event.set()


addr = ('127.0.0.1',9999)
server = socketserver.ThreadingTCPServer(addr,Myhandler)

server.serve_forever()

print('-------------[end]--------------------')
server.shutdown()

server.server_close()
           

运行结果:

<socketserver.ThreadingTCPServer object at 0x7f1c59c66a58> ('127.0.0.1', 59624) <socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 59624)>
b'Your msg = hello\r\n'
b'Your msg = python\r\n'
b'Your msg = quit\r\n'
b'Your msg = '
b'Your msg = '
           

改进:

import socketserver
import threading
import logging

logging.basicConfig(level=logging.INFO)


class MyHandler(socketserver.BaseRequestHandler):
    # 客户端信息
    clients = {}

    def setup(self):
        self.event = threading.Event()

    def handle(self):
        # 接受到了数据,分发
        conn = self.request
        self.clients[self.client_address] = conn
        while not self.event.is_set():
            try:
                data = conn.recv(1024).decode().strip()
                #处理客户段主动断开的异常(非quit)
                if not data:
                    raise BrokenPipeError
            except Exception as e:
                logging.info(e)
                data = 'quit'

            logging.info(data)

            # 客户端通知,退出机制
            if data == 'quit':
                logging.info('quit!')
                break

            msg = 'ack {}\n'.format(data)

            for c in self.clients.values():
                c.send(msg.encode())


    def finish(self):
        super().finish()
        self.event.set()
        self.clients.pop(self.client_address)

ip = '127.0.0.1'
port = 9999
addr = (ip, port)
server = socketserver.ThreadingTCPServer(addr, MyHandler)
threading.Thread(target=server.serve_forever, name='myserver', daemon=True).start()  # 需等待客户端退出后,主线程才能正常结束

import myutils

myutils.showthreads()

while True:
    cmd = input('>>>>').strip()
    if cmd == 'quit':
        server.shutdown()
        server.server_close()
        break
           
实用:python网络开发中多人聊天室的实现(socketserver)
实用:python网络开发中多人聊天室的实现(socketserver)

运行结果:

>>>>INFO:root:[<_MainThread(MainThread, started 140073430714112)>, <Thread(myserver, started daemon 140073405835008)>, <Thread(showthread, started daemon 140073397442304)>]
INFO:root:[<_MainThread(MainThread, started 140073430714112)>, <Thread(myserver, started daemon 140073405835008)>, <Thread(Thread-1, started 140073389049600)>, <Thread(Thread-2, started 140073177708288)>, <Thread(showthread, started daemon 140073397442304)>]
INFO:root:hello
INFO:root:[<_MainThread(MainThread, started 140073430714112)>, <Thread(myserver, started daemon 140073405835008)>, <Thread(Thread-1, started 140073389049600)>, <Thread(Thread-2, started 140073177708288)>, <Thread(showthread, started daemon 140073397442304)>]
INFO:root:python
INFO:root:quit
INFO:root:quit!
INFO:root:[<_MainThread(MainThread, started 140073430714112)>, <Thread(myserver, started daemon 140073405835008)>, <Thread(Thread-2, started 140073177708288)>, <Thread(showthread, started daemon 140073397442304)>]
INFO:root:quit
INFO:root:quit!
INFO:root:[<_MainThread(MainThread, started 140073430714112)>, <Thread(myserver, started daemon 140073405835008)>, <Thread(showthread, started daemon 140073397442304)>]
quit