Python

Python 문법 기초 37 - 멀티 채팅 서버 프로그램(socket + thread)

코딩탕탕 2022. 10. 23. 14:02

 

# 멀티 채팅 서버 프로그램 - socket + thread
import socket
import threading

ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ss.bind(('127.0.0.1', 5000))
ss.listen(5)
print('채팅 서버 서비스 시작...')

users = []

def chatUser(conn):
    name = conn.recv(1024)
    data = '^^ ' + name.decode('utf-8') + '님 입장'
    print(data)
    
    try:
        for p in users:
            p.send(data.encode('utf-8'))
            
        while True:
            msg = conn.recv(1024)
            if not msg:continue
            data = name.decode('utf-8') + '님 메세지:' + msg.decode('utf-8')
            print('수신 내용 : ', data)
            for p in users:
                p.send(data.encode('utf-8'))
            
    except:
        users.remove(conn) # user가 빠져나갔을 때 err 를 일으킴으로 해당 user를 삭제한다.
        data = '~~~' + name.decode('utf-8') + '님 퇴장 ~~'
        print(data)
        if users:
            for p in users:
                p.send(data.encode('utf-8'))
        else:
            print('사용자가 없습니다.')
            
    
while True:
    conn, addr = ss.accept()
    users.append(conn) # 클라이언트를 저장
    th = threading.Thread(target=chatUser, arg=(conn,))
    th.start()

여러 명이 들어와서 채팅을 하므로 thread를 돌리면서 모든 접속자와 채팅을 할 수 있게 된다.(멀티 테스킹)

user가 나갔을 때 err를 일으키므로 excet에 빠져나간 user의 id를 삭제한다.

 

 

# 채팅 클라이언트

import socket
import threading
import sys

def handle(socket):
    while True:
        data = socket.recv(1024)
        if not data:continue
        print(data.decode('utf-8'))

# 파이썬의 표준출력은 버퍼링이 되는데 이때 버퍼를 비우기
sys.stdout.flush()

name = input('채팅 아이디 입력:')
cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cs.connect(('127.0.0.1', 5000))
cs.send(name.encode('utf_8'))

th = threading.Thread(target=handle, args=(cs, ))
th.start()

while True:
    msg = input()
    sys.stdout.flush()
    if not msg:continue
    cs.send(msg.encode('utf_8'))
    
cs.close()

IP 주소는 자신의 번호인 127.0.0.1로 설정해놨지만 클라이언트에서는 ip주소를 채팅할 컴퓨터의 ip주소를 적으면 그 컴퓨터와 채팅 가능하다.