이 카테고리는 국비지원 과정으로 [계룡건설] 빅데이터 기반 GreenTech SW개발자 과정에서 학습하는 내용을 정리하는 공간입니다.
Python TCP 채팅 서버 & 클라이언트 상세 정리
1. 개요
이 프로젝트는 Python의 socket과 socketserver 모듈을 활용한 TCP 기반 채팅 서버와 클라이언트 구현 예제이다. 클라이언트는 GUI 기반(Tkinter)이며, 서버는 멀티스레드 방식으로 여러 클라이언트와의 동시 연결을 처리할 수 있도록 설계되었다.
본 문서에서는 TCP 통신 방식, BaseRequestHandler 역할, request 객체 활용, 그리고 주요 기능의 상세 구현을 설명한다.
2. TCP 통신 개념 및 구조
TCP 통신이란?
TCP(Transmission Control Protocol)는 연결 지향적 프로토콜로, 서버와 클라이언트가 3-way handshake를 통해 연결을 설정한 후 신뢰성 있는 데이터 전송을 수행한다.
TCP 연결 과정
- 3-Way Handshake (연결 설정)
- 클라이언트가 서버에게 SYN 패킷 전송 (연결 요청)
- 서버가 클라이언트에게 SYN-ACK 패킷 전송 (요청 수락)
- 클라이언트가 서버에게 ACK 패킷 전송 (연결 확인)
- 데이터 전송
- 서버와 클라이언트 간에 데이터가 순서대로 전송됨.
- 손실된 패킷은 재전송하여 데이터 무결성 유지.
- 4-Way Handshake (연결 종료)
- 한쪽에서 FIN 패킷을 보내 연결 종료 요청.
- 상대방이 ACK로 응답 후 FIN 패킷 전송.
- 마지막으로 ACK를 보내 연결이 종료됨.
3. 서버 구현 (socketserver 활용)
socketserver.BaseRequestHandler 란?
socketserver 모듈은 Python에서 TCP 서버를 간편하게 구현할 수 있도록 제공되는 모듈이다.
주요 역할
- 클라이언트 연결을 처리하는 핵심 클래스.
- handle() 메서드를 오버라이딩하여 요청을 처리.
- 멀티스레드 환경에서는 ThreadingMixIn과 함께 사용 가능.
서버 클래스 구성
import socketserver
class myTcpHandler(socketserver.BaseRequestHandler):
def handle(self):
print(f'클라이언트 연결: {self.client_address}')
while True:
data = self.request.recv(1024).decode()
if not data:
break
print(f'[{self.client_address}] {data}')
self.request.sendall(data.encode()) # 에코 서버 역할
- handle(): 클라이언트의 요청을 처리하는 메서드.
- self.request: 클라이언트의 요청 데이터를 받는 소켓 객체.
멀티스레드 지원 (ThreadingMixIn)
class ChatingServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
- ThreadingMixIn을 사용하여 멀티스레드로 동작하도록 설정.
서버 실행
server = ChatingServer(('192.168.0.10', 9900), myTcpHandler)
server.serve_forever()
- 지정된 IP와 포트에서 서버 실행.
- 여러 클라이언트를 동시에 처리 가능.
4. 클라이언트 구현 (Tkinter GUI)
클라이언트 역할
- 서버에 연결 후 메시지를 주고받음.
- GUI를 통해 입력 및 출력 인터페이스 제공.
- 특정 메시지 패턴 (>>>, <<<)에 따라 색상 변경.
클라이언트 코드 주요 부분
import socket
from threading import Thread
import tkinter
tk = tkinter.Tk()
tk.geometry("500x200")
HOST = '192.168.0.10'
PORT = 9900
# 서버에서 메시지 수신
def rcvMsg(sock):
while True:
try:
data = sock.recv(1024).decode()
if not data:
break
entry2.insert(0, data + '\n')
except:
pass
# 서버에 메시지 전송
def onClick():
sock.send(entry.get().encode())
entry.delete(0, tkinter.END)
# 서버와 연결 시작
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
# 수신 스레드 실행
Thread(target=rcvMsg, args=(sock,), daemon=True).start()
tk.mainloop()
주요 기능
- socket.connect((HOST, PORT)) → 서버에 연결.
- Thread(target=rcvMsg, args=(sock,), daemon=True).start() → 서버에서 수신하는 스레드 실행.
- entry.insert(0, data + '\n') → GUI에 메시지 추가.
- sock.send(entry.get().encode()) → 메시지 전송.
5. 데이터베이스 연동 (MySQL)
서버에서는 사용자의 로그인 정보와 채팅 로그를 MySQL에 저장한다.
데이터베이스 연결
import pymysql
def get_db_connection():
return pymysql.connect(
host='localhost', user='root', password='0000', database='chatmember', port=3306, autocommit=True
)
- autocommit=True: 변경 사항이 즉시 적용되도록 설정.
사용자 추가 및 로그 업데이트
def update_user_in_db(username, password):
conn = get_db_connection()
with conn.cursor() as cursor:
cursor.execute("CREATE TABLE IF NOT EXISTS members (username VARCHAR(255) PRIMARY KEY, password VARCHAR(255))")
cursor.execute("INSERT IGNORE INTO members (username, password) VALUES (%s, %s)", (username, password))
conn.close()
- INSERT IGNORE: 중복된 값이 있을 경우 무시하고 진행.
- CREATE TABLE IF NOT EXISTS: 테이블이 없으면 생성.
6. 정리 및 개선점
정리
- TCP 서버-클라이언트 연결 구조를 이해할 수 있다.
- socketserver.BaseRequestHandler를 활용하여 요청을 처리할 수 있다.
- Tkinter를 사용하여 간단한 GUI 클라이언트를 만들 수 있다.
- MySQL과 연동하여 사용자 정보 및 로그를 저장할 수 있다.
개선 가능점
- 보안 강화: 비밀번호를 평문으로 저장하지 않고 해싱 기법 (bcrypt) 사용.
- GUI 개선: 메시지 스타일을 추가하고, 사용자 리스트 기능 강화.
- 멀티룸 채팅 지원: 특정 채팅방을 생성하여 사용자가 참여할 수 있도록 개선.
'국비지원교육 > [계룡건설] 빅데이터 기반 GreenTech SW개발자' 카테고리의 다른 글
**[계룡건설] GreenTech SW개발자 - Python 학습 노트 .14** (0) | 2025.03.21 |
---|---|
**[계룡건설] GreenTech SW개발자 - Python 학습 노트 .13** (0) | 2025.03.21 |
**[계룡건설] GreenTech SW개발자 - Python 학습 노트 .11** (0) | 2025.03.05 |
**[계룡건설] GreenTech SW개발자 - SQL 학습 노트** (0) | 2025.02.17 |
**[계룡건설] GreenTech SW개발자 - JavaScript 학습 노트 .1** (0) | 2025.02.17 |