3강. 소켓의 역할과 동작 흐름

0. 학습 목표
→ 이번 글에서 무엇을 이해하고, 무엇을 정리하고, 무엇을 확인할지 먼저 정리합니다.
0.1 이번 글에서 다룰 내용
이번 글은 개념 중심 강의입니다.
1강과 2강에서 서버·클라이언트 역할, IP·Port, TCP 연결 방식을 배웠습니다.
이번 강의는 그 개념들을 실제 Python 코드에서 다루기 위해 Socket 을 사용합니다.
Socket은 IP, Port, TCP를 코드 안에서 사용할 수 있게 해 주는 프로그래밍 추상화입니다. 개발자는 TCP 연결이 내부에서 어떻게 만들어지는지 매번 직접 처리하지 않고, 소켓 함수 흐름을 따라 서버와 클라이언트를 구현합니다.
서버: socket() → bind() → listen() → accept() → recv()/send() → close()
클라이언트: socket() → connect() → send()/recv() → close()
이번 강의에서 배우는 소켓 흐름은 최종 채팅 프로젝트의 chat_server/server.py와 chat_client/network_client.py에서 그대로 사용됩니다.
4강부터 직접 코드로 작성하게 될 Socket의 개념을 이해합니다.
| 구분 | 내용 |
| 이해할 것 | 소켓의 역할, 소켓 추상화, 서버 소켓·클라이언트 소켓·연결 소켓의 차이 |
| 정리할 것 | 서버가 기다리는 순서(bind → listen → accept)와 클라이언트가 접속하는 순서(connect) |
| 확인할 것 | 다음 강의에서 작성할 서버 코드의 흐름을 말로 설명할 수 있는지 |
0.2 앞으로 만들 프로젝트 구조 미리보기
이번 강의에서는 새 파일을 만들거나 수정하지 않습니다.
4강에서 chat_server/server.py를, 5강에서 chat_client/client.py를 생성할 예정입니다.
chat_server/
└── server.py ← 4강에서 생성 예정
chat_client/
└── client.py ← 5강에서 생성 예정
1. 핵심 개념 이해하기
→ 소켓의 역할과 서버 소켓·클라이언트 소켓·연결 소켓의 차이를 이해합니다.
1.1 소켓의 역할
Socket은 IP, Port, TCP를 개발자가 실제 프로그램을 만들 때는 다음 작업을 소켓 함수로 처리합니다.
1. TCP 방식으로 통신할 소켓을 만든다
2. 서버는 서버 소켓에 IP와 Port를 묶는다
3. 클라이언트는 서버 IP와 Port를 사용해 접속한다
4. 연결이 만들어지면 데이터를 주고 받는다
5. 통신이 끝나면 소켓을 닫는다

소켓은 택배 송장에 비유할 수 있습니다. 택배원이 송장에 적힌 주소(IP)와 받는 사람(Port), 배송 방식(TCP)을 기준으로 배송을 진행하듯, 소켓도 이 세 정보를 묶어 데이터를 전송합니다.
Python에서는 socket 모듈로 소켓을 만듭니다.
지금 이 코드를 완전히 외울 필요는 없습니다. 두 가지 의미만 가볍게 알고 넘어가면 됩니다.
import socket
my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
| 코드 | 의미 |
socket.AF_INET |
IPv4 주소 체계를 사용하겠다는 뜻 |
socket.SOCK_STREAM |
TCP 방식으로 연결하겠다는 뜻 |
이 한 줄 안에는 2강에서 배운 IP와 TCP 개념이 이미 들어 있습니다.
✔ 확인 기준: 소켓을 "네트워크 통신을 코드에서 다루기 위한 도구"라고 설명할 수 있으면 완료입니다. 소켓을 IP나 Port 자체로 설명하거나 물리적인 케이블·장치처럼 이해하고 있다면 이 섹션을 다시 확인하세요.
2.2 소켓 흐름 확인하기

실제 코드는 4강과 5강에서 작성합니다. 지금은 흐름만 확인합니다.
# 서버 (server.py) — 대기하고 수락하는 쪽
서버 소켓 준비
접속 대기 # 클라이언트가 올 때까지 여기서 기다림
클라이언트 접속 수락
메시지 받기
메시지 처리 후 응답 보내기
# 클라이언트 (main.py) — 연결 요청하는 쪽
서버 주소와 포트 설정
서버에 연결 요청
메시지 보내기
서버 응답 받기
✔ 확인 기준: chat_server/server.py와 chat_client/main.py가 각각 어떤 역할을 하는지 설명할 수 있으면 완료입니다.
2. 소켓 사용 이해하기
→ 서버와 클라이언트의 전체 연결 흐름을 시간 순서로 확인하고, send와 recv의 역할을 구분합니다.
2.1 소켓 흐름

| 클라이언트(Client) 흐름 | 서버(Server) 흐름 | ||
| [1]생성 | 1. 클라이언트 소켓* 생성 | [1]생성 | 1. 서버 소켓* 생성 |
| [2]결합 | 2. 서버 소켓에 IP 주소와 Port 번호 결합 | ||
| [3]대기 | 3. 클라이언트 요청 대기 | ||
| [2]연결 | 2. 서버로 연결 요청 | ||
| [4]수락 | 4. 클라이언트 요청 정보와 서버 소켓 정보를 결합해 연결 소켓* 을 생성 | ||
| [3]송수신 | 3. 서버 소켓에서 연결 수락 후, 데이터 송수신 | [5]송수신 | 5. 연결 소켓을 통한 데이터를 송수신 |
| [4]닫음 | 4. 통신이 완료되면, 소켓 닫음 | [6]닫음 | 6. 통신이 완료되면, 연결 소켓을 닫음 |
* 서버 소켓은, 일반적으로 다수의 클라으언트 소켓으로부터 연결 요청을 받는다.
* 클라이언트 소켓은, 서버와 연결 된 뒤, 별도의 소켓을 생성하지 않고, 같은 소켓을 사용한다.
* 연결 소켓은, 서버 소켓에서 클라이언트와 연결된 연결 소켓으로 서버 소켓과 다르다.
✔ 확인 기준: 서버 소켓·클라이언트 소켓·연결 소켓의 역할을 각각 설명할 수 있으면 완료입니다. server_socket과 accept() 후 생기는 client_socket을 같은 역할로 이해하고 있다면 1.2를 다시 확인하세요.
2.2 accept() 전후 역할이 다르다
초급자가 가장 헷갈리는 지점이 accept()입니다.
서버가 처음 만든 소켓 (server_socket)
→ 접속 요청을 기다리는 소켓
accept() 후에 생기는 소켓 (client_socket)
→ 특정 클라이언트와 실제로 대화하는 소켓
| 구분 | 서버 | 클라이언트 |
| 처음 만드는 소켓 | 접속을 기다리는 서버 소켓 | 서버에 접속할 클라이언트 소켓 |
| 연결 시점 | accept() 후 연결 소켓이 따로 생김 |
connect() 성공 후 같은 소켓 사용 |
| 데이터 송수신 | accept()가 돌려준 연결 소켓으로 송수신 |
처음 만든 클라이언트 소켓으로 송수신 |
2.4 연결 후에는 send()와 recv()로 데이터를 주고받는다
연결은 길을 만든 것입니다. 실제 데이터를 보내고 받으려면 별도의 동작이 필요합니다.
클라이언트 send("안녕하세요")
↓
네트워크를 통해 이동
↓
서버 recv()
↓
서버가 "안녕하세요"를 받음
주의할 점이 있습니다. 한쪽이 send()하면 반대쪽은 recv()로 받아야 합니다. 양쪽이 모두 recv()만 하고 있으면 서로가 보내기를 기다리는 상태가 되어 프로그램이 멈춘 것처럼 보일 수 있습니다. 이 문제는 6강과 7강에서 실제 송수신 코드를 작성할 때 다시 다룹니다.
2.5 연결과 메시지 전송은 다른 단계다
connect()가 성공했다고 해서 메시지를 보낸 것은 아닙니다.
connect() 성공 → 서버와 클라이언트 사이에 통신할 길이 만들어짐
send() 실행 → 실제 데이터가 상대에게 보내짐
recv() 실행 → 상대가 보낸 데이터를 받음
클라이언트에서 connect()는 성공했는데 서버 화면에 메시지가 보이지 않는다면, 연결 자체보다 send()와 recv() 흐름을 먼저 의심해야 합니다.
✔ 확인 기준: 서버는 bind() → listen() → accept(), 클라이언트는 connect()가 핵심이라고 말할 수 있으면 완료입니다. connect()를 서버에서 쓰는 함수로, accept()를 클라이언트에서 쓰는 함수로 이해하고 있다면 1.2와 2.1을 다시 확인하세요.
2.6 자주 하는 오해
| 오해 | 올바른 정리 |
| 소켓은 서버에만 있다 | 서버도 소켓을 만들고 클라이언트도 소켓을 만든다 |
| 소켓은 IP와 같은 뜻이다 | IP는 주소이고, 소켓은 그 주소와 통신 방식을 코드에서 사용하는 도구다 |
| connect()가 성공하면 메시지가 자동으로 간다 | 연결 후 실제 데이터 전송은 send()로 따로 해야 한다 |
| accept() 후에도 server_socket으로 데이터를 받는다 | accept()가 돌려준 연결 소켓(client_socket)으로 데이터를 주고받는다 |
3. 다음 강의로 이어지는 부분
→ 핵심 개념을 요약하고 4강에서 작성할 서버 코드 흐름을 예고합니다.
| 개념 | 개발자 관점의 코드 흐름 |
| 서버 역할 | bind(), listen(), accept()로 기다리는 구조를 만든다 |
| 클라이언트 역할 | connect()로 서버에 연결을 요청한다 |
| IP와 포트 | bind()와 connect()에 들어가는 주소 정보로 사용된다 |
| TCP | socket.AF_INET, socket.SOCK_STREAM으로 TCP 소켓을 만들 때 사용된다 |
| 메시지 송수신 | 연결 후 send()와 recv()로 처리한다 |
다음 4강에서는 이번 강의에서 정리한 흐름 중 서버 쪽을 실제 코드로 만듭니다. 다음 강의로 넘어가기 전에 이 문장을 스스로 설명해 보세요.
서버는 소켓을 만든 뒤 IP와 포트에 묶고, 접속을 기다리다가 accept()로 클라이언트를 받은 다음, 연결 소켓을 통해 데이터를 주고받는다.
→ 다음 강의 (4강): 이번 강의에서 정리한 서버 소켓 흐름(socket() → bind() → listen() → accept())을 chat_server/server.py에 실제 코드로 작성하고 실행합니다.