• 티스토리 홈
  • 프로필사진
    소쩍소쩍이
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
소쩍소쩍이
  • 프로필사진
    소쩍소쩍이
    • 분류 전체보기 (89)
      • 파이썬 (18)
        • 문제 및 예제 (8)
      • PySide6 (24)
        • Signal & Slot (6)
        • Layout (8)
        • Model & View (3)
        • File (4)
        • Resource (3)
      • Server - Client (17)
        • GUI 채팅 (1)
      • MySQL (4)
      • 리눅스 (5)
      • 아두이노 (0)
      • 일지 (20)
  • GitHub
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    # Home
    # 공지사항
    #
    # 태그
    # 검색결과
    # 방명록
    • 전체 채팅 브로드캐스팅
      2026년 06월 23일
      • 소쩍소쩍이
      • 작성자
      • 2026.06.23.:18

      브로드캐스팅 구현하기

      지금까지는 서버와 클라이언트가 1:1로만 메시지를 주고받았다.

      이번에는 한 클라이언트가 보낸 메시지를 다른 모든 클라이언트에게 전달하는 브로드캐스팅 기능을 구현한다.

       

      브로드캐스팅 규칙

      규칙 내용
      보낸 클라이언트 자기 메시지를 다시 받지 않는다
      나머지 클라이언트 보낸 사람의 메시지를 받는다
      메시지 형식 클라이언트 주소와 메시지를 함께 표시한다
      종료 exit 입력 시 연결을 종료한다

       

      예시
      ('127.0.0.1', 52344): 안녕하세요

       

      서버 - broadcast() 함수 만들기

      브로드캐스팅은 현재 접속 중인 모든 클라이언트를 순회하면서 메시지를 전달하는 방식으로 구현한다.

       

      📄 broadcast() 코드 보기
      def broadcast(message, sender_socket):
          for client in clients:
              if client != sender_socket:
                  try:
                      client.send(message.encode("utf-8"))
                  except:
                      if client in clients:
                          clients.remove(client)

       

      코드 의미
      for client in clients: 접속 중인 모든 클라이언트를 순회
      if client != sender_socket: 보낸 사람은 제외
      try / except 끊어진 소켓 전송 오류 처리

       

      주의
      sender_socket 제외 조건이 없으면 자신이 보낸 메시지가 자기 화면에도 다시 나타난다.

       

      handle_client()에서 broadcast() 호출

      메시지를 받은 뒤 브로드캐스트 함수를 호출한다.

      broadcast_message = f"{client_address}: {message}"
      broadcast(broadcast_message, client_socket)

      메시지 내용만 보내는 것이 아니라 누가 보냈는지 함께 포함해서 전달한다.

       

      서버 메인 루프

      접속한 클라이언트를 clients 목록에 추가한 뒤 전용 스레드를 시작한다.

       

      📄 서버 메인 루프 코드 보기
      with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
          server_socket.bind((HOST, PORT))
          server_socket.listen()
      
          print("전체 채팅 서버를 시작합니다.")
          print("클라이언트 접속 대기 중...")
      
          while True:
              client_socket, client_address = server_socket.accept()
      
              clients.append(client_socket)
      
              client_thread = threading.Thread(
                  target=handle_client,
                  args=(client_socket, client_address)
              )
              client_thread.start()

       

      클라이언트 - 수신 스레드 추가하기

      전체 채팅에서는 언제 다른 사용자가 메시지를 보낼지 알 수 없다.

      내가 입력을 기다리는 동안에도 다른 사람의 메시지가 도착할 수 있기 때문에 입력과 수신을 분리해야 한다.

       

      역할 담당
      사용자 입력 및 전송 메인 흐름
      메시지 수신 수신 스레드

       

      receive_messages() 함수

      📄 receive_messages() 코드 보기
      def receive_messages(client_socket):
          while True:
              try:
                  data = client_socket.recv(1024)
      
                  if not data:
                      print("서버와의 연결이 끊어졌습니다.")
                      break
      
                  message = data.decode("utf-8")
                  print(f"\n{message}")
      
              except:
                  break

       

      수신 스레드 시작하기

      클라이언트 실행 시 수신 전용 스레드를 생성한다.

       

      📄 클라이언트 전체 코드 보기
      import socket
      import threading
      
      HOST = "127.0.0.1"
      PORT = 5000
      
      def receive_messages(client_socket):
          while True:
              try:
                  data = client_socket.recv(1024)
      
                  if not data:
                      print("서버와의 연결이 끊어졌습니다.")
                      break
      
                  message = data.decode("utf-8")
                  print(f"\n{message}")
      
              except:
                  break
      
      with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client_socket:
          client_socket.connect((HOST, PORT))
      
          receive_thread = threading.Thread(
              target=receive_messages,
              args=(client_socket,)
          )
      
          receive_thread.daemon = True
          receive_thread.start()
      
          while True:
              message = input("")
              client_socket.send(message.encode("utf-8"))
      
              if message == "exit":
                  break

       

      daemon 옵션 이해하기

      설정 동작
      daemon = False 수신 스레드가 끝날 때까지 프로그램 종료 대기
      daemon = True 메인 흐름 종료 시 수신 스레드도 함께 종료

       

      주의
      daemon 설정은 반드시 start() 전에 해야 한다.
      start() 이후 설정하면 RuntimeError가 발생한다.

       

      흔한 오류와 해결 방법

      오류 상황 원인 및 해결 방법
      메시지가 다른 사람에게 보이지 않음 broadcast() 호출 여부와 clients.append() 실행 여부 확인
      내 메시지가 내 화면에도 보임 if client != sender_socket 조건 확인
      다른 사람 메시지를 받지 못함 receive_thread.start() 실행 여부 확인
      exit 후 종료되지 않음 daemon=True 설정 확인
      RuntimeError: cannot set daemon after start daemon 설정 위치 확인
      클라이언트 종료 후 서버 오류 발생 broadcast() 내부 try/except 확인
      입력 줄과 메시지가 섞여 보임 터미널 환경에서는 정상 현상

       

      정리
      브로드캐스팅은 한 사용자가 보낸 메시지를 다른 모든 사용자에게 전달하는 기능이다.

      서버는 clients 목록을 순회하면서 sender를 제외한 나머지 사용자에게 메시지를 전송한다.

      클라이언트는 입력과 수신을 동시에 처리해야 하므로 receive_messages() 스레드를 추가해 별도로 메시지를 받아야 한다.

      'Server - Client' 카테고리의 다른 글

      JSON 기반 메시지 타입 설계  (0) 2026.06.23
      왜 메시지 규칙이 필요한가  (0) 2026.06.23
      접속자 목록 관리  (0) 2026.06.23
      스레드로 클라이언트 처리  (0) 2026.06.23
      스레드 개념과 기초 사용법  (0) 2026.06.23
      다음글
      다음 글이 없습니다.
      이전글
      이전 글이 없습니다.
      댓글
    조회된 결과가 없습니다.
    스킨 업데이트 안내
    현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
    ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
    목차
    표시할 목차가 없습니다.
      • 안녕하세요
      • 감사해요
      • 잘있어요

      티스토리툴바