python 간단 한 채 팅 애플 릿 구현

개요
이것 은 python 을 사용 하여 간단 한 채 팅 방 을 실현 하 는 기능 입 니 다.그 안에 단체 채 팅,개인 채 팅 두 가지 채 팅 방식 이 포함 되 어 있 습 니 다.실현 하 는 방식 은 소켓 프로 그래 밍 을 사용 하 는 TCP 프로 토 콜 c/s 구 조 를 사용 하 는 채 팅 방 입 니 다.
사고의 방향 을 실현 하 다.
x01 서버 구축
우선,서버 에서 socket 을 사용 하여 메 시 지 를 받 아들 이 고 하나의 socket 요청 을 받 아들 일 때마다 새로운 스 레 드 를 열 어 메시지 의 배포 와 수용 을 관리 하 는 동시에 하나의 handler 가 존재 하여 모든 스 레 드 를 관리 하여 채 팅 방 의 각종 기능 에 대한 처 리 를 실현 합 니 다.
x02 클 라 이언 트 의 구축
클 라 이언 트 의 구축 은 서버 보다 훨씬 간단 합 니 다.클 라 이언 트 의 역할 은 메시지 의 발송 과 수용,그리고 특정한 규칙 에 따라 특정한 문 자 를 입력 하여 서로 다른 기능 의 사용 을 실현 하 는 것 입 니 다.따라서 클 라 이언 트 에 서 는 두 개의 라인 만 사용 해 야 합 니 다.하 나 는 메 시 지 를 받 아들 이 는 것 이 고 하 나 는 메 시 지 를 보 내 는 데 전문 적 인 것 입 니 다.
왜 하 나 를 사용 하지 않 는 지 에 대해 서 는 하나만 사용 하면 메 시 지 를 받 았 을 때 보 내기 전에 메 시 지 를 받 는 것 이 막 힌 상태 이기 때 문 입 니 다.마찬가지 로 메 시 지 를 보 내 는 것 도 마찬가지 입 니 다.그러면 이 두 가지 기능 을 한 곳 에 두 고 실현 하면 계속 보 내 거나 받 아들 일 수 없 기 때 문 입 니 다.
실현 방식
서버 구현


import json
import threading
from socket import *
from time import ctime


class PyChattingServer:
    __socket = socket(AF_INET, SOCK_STREAM, 0)
    __address = ('', 12231)

    __buf = 1024

    def __init__(self):
        self.__socket.bind(self.__address)
        self.__socket.listen(20)
        self.__msg_handler = ChattingHandler()

    def start_session(self):
        print('      ...\r
') try: while True: cs, caddr = self.__socket.accept() # handler , socket self.__msg_handler.start_thread(cs, caddr) except socket.error: pass class ChattingThread(threading.Thread): __buf = 1024 def __init__(self, cs, caddr, msg_handler): super(ChattingThread, self).__init__() self.__cs = cs self.__caddr = caddr self.__msg_handler = msg_handler # def run(self): try: print('... :', self.__caddr) data = ' PY_CHATTING! cooooool ( `)\r
' self.__cs.sendall(bytes(data, 'utf-8')) while True: data = self.__cs.recv(self.__buf).decode('utf-8') if not data: break self.__msg_handler.handle_msg(data, self.__cs) print(data) except socket.error as e: print(e.args) pass finally: self.__msg_handler.close_conn(self.__cs) self.__cs.close() class ChattingHandler: __help_str = "[ SYSTEM ]\r
" \ " /ls, \r
" \ " /h, \r
" \ " @ ( )+ , \r
" \ " /i, \r
" \ " /i, \r
" \ " / " __buf = 1024 __socket_list = [] __user_name_to_socket = {} __socket_to_user_name = {} __user_name_to_broadcast_state = {} def start_thread(self, cs, caddr): self.__socket_list.append(cs) chat_thread = ChattingThread(cs, caddr, self) chat_thread.start() def close_conn(self, cs): if cs not in self.__socket_list: return # socket nickname = "SOMEONE" if cs in self.__socket_list: self.__socket_list.remove(cs) # socket username if cs in self.__socket_to_user_name: nickname = self.__socket_to_user_name[cs] self.__user_name_to_socket.pop(self.__socket_to_user_name[cs]) self.__socket_to_user_name.pop(cs) self.__user_name_to_broadcast_state.pop(nickname) nickname += " " # self.broadcast_system_msg(nickname + " PY_CHATTING") # def handle_msg(self, msg, cs): js = json.loads(msg) if js['type'] == "login": if js['msg'] not in self.__user_name_to_socket: if ' ' in js['msg']: self.send_to(json.dumps({ 'type': 'login', 'success': False, 'msg': ' ' }), cs) else: self.__user_name_to_socket[js['msg']] = cs self.__socket_to_user_name[cs] = js['msg'] self.__user_name_to_broadcast_state[js['msg']] = True self.send_to(json.dumps({ 'type': 'login', 'success': True, 'msg': ' , /ls , /help ( / )' }), cs) # , self.broadcast_system_msg(js['msg'] + " ") else: self.send_to(json.dumps({ 'type': 'login', 'success': False, 'msg': ' ' }), cs) # , elif js['type'] == "broadcast": if self.__user_name_to_broadcast_state[self.__socket_to_user_name[cs]]: self.broadcast(js['msg'], cs) else: self.send_to(json.dumps({ 'type': 'broadcast', 'msg': ' ' }), cs) elif js['type'] == "ls": self.send_to(json.dumps({ 'type': 'ls', 'msg': self.get_all_login_user_info() }), cs) elif js['type'] == "help": self.send_to(json.dumps({ 'type': 'help', 'msg': self.__help_str }), cs) elif js['type'] == "sendto": self.single_chatting(cs, js['nickname'], js['msg']) elif js['type'] == "ignore": self.exchange_ignore_state(cs) def exchange_ignore_state(self, cs): if cs in self.__socket_to_user_name: state = self.__user_name_to_broadcast_state[self.__socket_to_user_name[cs]] if state: state = False else: state = True self.__user_name_to_broadcast_state.pop(self.__socket_to_user_name[cs]) self.__user_name_to_broadcast_state[self.__socket_to_user_name[cs]] = state if self.__user_name_to_broadcast_state[self.__socket_to_user_name[cs]]: msg = " " else: msg = " " self.send_to(json.dumps({ 'type': 'ignore', 'success': True, 'msg': '[TIME : %s]\r
[ SYSTEM ] : %s\r
' % (ctime(), " , " + msg) }), cs) else: self.send_to({ 'type': 'ignore', 'success': False, 'msg': ' ' }, cs) def single_chatting(self, cs, nickname, msg): if nickname in self.__user_name_to_socket: msg = '[TIME : %s]\r
[ %s CHATTING TO %s ] : %s\r
' % ( ctime(), self.__socket_to_user_name[cs], nickname, msg) self.send_to_list(json.dumps({ 'type': 'single', 'msg': msg }), self.__user_name_to_socket[nickname], cs) else: self.send_to(json.dumps({ 'type': 'single', 'msg': ' ' }), cs) print(nickname) def send_to_list(self, msg, *cs): for i in range(len(cs)): self.send_to(msg, cs[i]) def get_all_login_user_info(self): login_list = "[ SYSTEM ] ALIVE USER : \r
" for key in self.__socket_to_user_name: login_list += self.__socket_to_user_name[key] + ",\r
" return login_list def send_to(self, msg, cs): if cs not in self.__socket_list: self.__socket_list.append(cs) cs.sendall(bytes(msg, 'utf-8')) def broadcast_system_msg(self, msg): data = '[TIME : %s]\r
[ SYSTEM ] : %s\r
' % (ctime(), msg) js = json.dumps({ 'type': 'system_msg', 'msg': data }) # for i in range(len(self.__socket_list)): if self.__socket_list[i] in self.__socket_to_user_name: self.__socket_list[i].sendall(bytes(js, 'utf-8')) def broadcast(self, msg, cs): data = '[TIME : %s]\r
[%s] : %s\r
' % (ctime(), self.__socket_to_user_name[cs], msg) js = json.dumps({ 'type': 'broadcast', 'msg': data }) # , for i in range(len(self.__socket_list)): if self.__socket_list[i] in self.__socket_to_user_name \ and self.__user_name_to_broadcast_state[self.__socket_to_user_name[self.__socket_list[i]]]: self.__socket_list[i].sendall(bytes(js, 'utf-8')) def main(): server = PyChattingServer() server.start_session() main()
클 라 이언 트 의 실현


import json
import threading
from socket import *

is_login = False
is_broadcast = True


class ClientReceiveThread(threading.Thread):
    __buf = 1024

    def __init__(self, cs):
        super(ClientReceiveThread, self).__init__()
        self.__cs = cs

    def run(self):
        self.receive_msg()

    def receive_msg(self):
        while True:
            msg = self.__cs.recv(self.__buf).decode('utf-8')
            if not msg:
                break
            js = json.loads(msg)
            if js['type'] == "login":
                if js['success']:
                    global is_login
                    is_login = True
                print(js['msg'])
            elif js['type'] == "ignore":
                if js['success']:
                    global is_broadcast
                    if is_broadcast:
                        is_broadcast = False
                    else:
                        is_broadcast = True
                print(js['msg'])
            else:
                if not is_broadcast:
                    print("[        ]")
                print(js['msg'])


class ClientSendMsgThread(threading.Thread):

    def __init__(self, cs):
        super(ClientSendMsgThread, self).__init__()
        self.__cs = cs

    def run(self):
        self.send_msg()

    #                    
    def send_msg(self):
        while True:
            js = None
            msg = input()
            if not is_login:
                js = json.dumps({
                    'type': 'login',
                    'msg': msg
                })
            elif msg[0] == "@":
                data = msg.split(' ')
                if not data:
                    print("     ")
                    break
                nickname = data[0]
                nickname = nickname.strip("@")
                if len(data) == 1:
                    data.append(" ")
                js = json.dumps({
                    'type': 'sendto',
                    'nickname': nickname,
                    'msg': data[1]
                })
            elif msg == "/help":
                js = json.dumps({
                    'type': 'help',
                    'msg': None
                })
            elif msg == "/ls":
                js = json.dumps({
                    'type': 'ls',
                    'msg': None
                })
            elif msg == "/i":
                js = json.dumps({
                    'type': 'ignore',
                    'msg': None
                })
            else:
                if msg[0] != '/':
                    js = json.dumps({
                        'type': 'broadcast',
                        'msg': msg
                    })
            if js is not None:
                self.__cs.sendall(bytes(js, 'utf-8'))


def main():
    buf = 1024
    #        ,        ,                   
    address = ("127.0.0.1", 12231)
    cs = socket(AF_INET, SOCK_STREAM, 0)
    cs.connect(address)
    data = cs.recv(buf).decode("utf-8")
    if data:
        print(data)
    receive_thread = ClientReceiveThread(cs)
    receive_thread.start()
    send_thread = ClientSendMsgThread(cs)
    send_thread.start()
    while True:
        pass


main()
이렇게 간단 한 채 팅 방 이 세 워 졌 다.
총결산
이 구현 채 팅 방 에서 저 는 json 형식의 문자열 정 보 를 사용 하여 작성 한 프로 토 콜 입 니 다.아마도 더 간단 한 방식 으로 실현 할 수 있 을 것 입 니 다.
사실 이 채 팅 방 은 가장 기본 적 인 socket 프로 그래 밍 의 실현 방안 이자 네트워크 에 속 하 는 비교적 간단 한 작성 입 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기