KRX 시세 데이터는 기본적으로 UDP Multicast로 송출되지만, 개발 환경이나 특정 솔루션(VND, 시세 분배 서버 등)을 거칠 때는 TCP Relay 방식을 사용하는 경우가 많습니다.
TCP는 UDP와 달리 1:1 연결(Connection-oriented) 방식이므로, 멀티캐스트 그룹 가입 과정이 필요 없고 서버의 IP와 포트로 직접 접속해야 합니다. 관련 커맨드를 정리해 드립니다.
1. 연결 상태 확인 (Connectivity Test)
가장 먼저 개발 서버에서 시세 제공 서버(Gateway)의 포트가 열려 있는지 확인합니다.
# nc(netcat)를 이용한 포트 확인
nc -zv <서버IP> <포트번호>
# 예: nc -zv 10.10.1.100 20001
# telnet을 이용한 확인
telnet <서버IP> <포트번호>
2. 데이터 실시간 흐름 확인 (Raw Data Stream)
TCP 연결을 맺고 들어오는 바이너리/텍스트 데이터를 화면에 출력합니다.
# nc를 이용해 수신된 데이터를 화면에 출력
nc <서버IP> <포트번호>
# 수신된 데이터를 파일로 저장하면서 확인 (디버깅용)
nc <서버IP> <포트번호> | tee market_data.log
3. tcpdump를 이용한 패킷 분석
TCP 핸드쉐이크가 잘 일어나는지, 데이터가 실제로 들어오는지 확인합니다.
# 특정 포트로 들어오는 TCP 패킷의 헤더와 데이터 확인
sudo tcpdump -i eth0 tcp port 20001 -X -nn
# 특정 IP와 통신하는 TCP 패킷만 필터링
sudo tcpdump -i eth0 host <서버IP> and tcp port <포트번호> -vv
4. tshark (Wireshark CLI) 활용
TCP 세그먼트를 재조합해서 보거나 페이로드만 추출할 때 유용합니다.
# 실시간으로 TCP 페이로드(데이터)를 헥사 형태로 출력
sudo tshark -i eth0 -f "tcp port 20001" -T fields -e data
5. Python을 이용한 간단한 TCP 수신 클라이언트

KRX 데이터는 보통 고정 길이 전문(Fixed Length) 구조입니다. TCP 특성상 패킷이 잘려서 올 수 있으므로(Fragmentation), 실제 개발 시에는 메시지 길이를 계산해서 읽어야 합니다. 테스트용 기본 코드는 다음과 같습니다.
import socket
SERVER_IP = '10.10.1.100'
SERVER_PORT = 20001
# TCP 소켓 생성
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# 서버 연결
sock.connect((SERVER_IP, SERVER_PORT))
print(f"Connected to {SERVER_IP}:{SERVER_PORT}")
while True:
# 데이터 수신 (버퍼 사이즈는 적절히 조절)
data = sock.recv(4096)
if not data:
print("Connection closed by server")
break
# 바이너리 데이터 출력
print(f"Received {len(data)} bytes")
print(data.hex()) # 헥사로 보기
# print(data.decode('cp949', errors='ignore')) # 한글 포함 시
except Exception as e:
print(f"Error: {e}")
finally:
sock.close()
6. socat을 이용한 브릿징/로깅
TCP로 받은 데이터를 다른 포트로 중계하거나 파일로 기록할 때 편리합니다.
# TCP 데이터를 받아서 파일에 이어쓰기(append)
socat TCP:<서버IP>:<포트번호> GOPEN:market_data.bin,append
⚠️ TCP 수신 시 주의사항 (UDP와 다른 점)
-
세션 연결(Handshake): UDP는 그냥 듣기만 하면 되지만, TCP는 서버가 살아있어야 하며 반드시 connect 과정이 성공해야 데이터가 흐릅니다.
-
데이터 경계(Message Framing): TCP는 ‘스트림’ 방식입니다. 서버가 100바이트 전문을 보냈어도 클라이언트는 50바이트, 50바이트씩 끊어서 받을 수 있습니다. 따라서 전문 헤더에 정의된 길이만큼 수신 버퍼에서 잘라 읽는 로직이 반드시 필요합니다.
-
방화벽(Outbound): 개발 서버에서 외부(또는 시세망)로 나가는 아웃바운드 TCP 연결이 허용되어 있는지 확인해야 합니다.
-
Keep-Alive: 장시간 데이터가 없을 경우 세션이 끊길 수 있으므로, TCP Keep-Alive 옵션을 설정하거나 애플리케이션 레벨에서 Heartbeat가 필요한지 확인하십시오.
어떤 방식(코스콤 Check, 직접 연동, 또는 사내 중계 서버)으로 받으시는지에 따라 전문 규격(헤더 길이 등)이 달라지므로, 해당 인터페이스 정의서(API 명세서)를 참고하여 recv 길이를 설정하시기 바랍니다.