질문)
송신하는 프로그램은 한줄씩 읽어서 보내지만, 수신하는측에서는 한줄씩 받는다고 보장할수 없겠죠? 수신측의 서버상태에 따라서, 한줄, 두줄, 세줄, 네줄 혹은 그 이상의 줄을 받을수도 있겠죠?
답변)
네, 정확하게 이해하셨습니다.
TCP는 “스트림(흐름)” 기반 프로토콜이기 때문에, 송신 측이 줄 단위(Send(line + delimiter))로 보냈더라도 수신 측은 반드시 줄 단위로 받는다는 보장은 없습니다.
🔄 TCP 수신의 핵심 개념
- TCP는 패킷을 보장된 순서로 “흐름(stream)” 형태로 전달합니다.
- 이 흐름 속에서 수신 측은 네트워크 상태, OS 버퍼 상황, 수신 처리 타이밍 등에 따라:
- 한 줄을 나눠서 여러 번 받을 수도 있고
- 여러 줄이 한 번에 도착할 수도 있습니다.
📌 예시
송신 측:
text
복사편집
1st line + [0D 0A FF] 2nd line + [0D 0A FF]
수신 측 stream.Read() 호출 결과는 다음과 같이 될 수 있습니다:
- 경우 1: 한 번 호출 → "1st line + 0D 0A FF + 2nd line + 0D 0A FF"
- 경우 2: 두 번 호출 → "1st line + 0D", "0A FF + 2nd line + 0D 0A"
- 경우 3: 세 번 호출 → "1st ", "line + 0D 0A FF", "2nd line + 0D 0A FF"
- 등등...
✅ 따라서 수신 측에서는 반드시 해야 할 것
1. 바이트 버퍼 누적
- 이전 Read에서 다 읽지 못한 데이터를 버퍼에 누적 유지해야 함
2. 패킷 구분자 기준으로 자르기
- 0x0D 0x0A 0xFF 시퀀스를 기준으로 정확하게 잘라서 한 패킷 추출해야 함
3. 조각남 데이터 유지
- 마지막 구분자 이후에 도달하지 못한 데이터는 다음 수신으로 이어서 누적
✅ 이 부분이 바로 List<byte> buffer + FindSeparator() 로직이 필요한 이유입니다.
앞서 작성한 HandleClient()의 이 부분이 그 역할을 하는 거죠:
while (true) { int bytesRead = stream.Read(recvBuf, 0, recvBuf.Length); if (bytesRead == 0) break; for (int i = 0; i < bytesRead; i++) buffer.Add(recvBuf[i]); while (true) { int sepIndex = FindSeparator(buffer); if (sepIndex < 0) break; byte[] packet = buffer.GetRange(0, sepIndex).ToArray(); buffer.RemoveRange(0, sepIndex + 3); // 0x0D 0x0A 0xFF 제거 string message = Encoding.ASCII.GetString(packet); Console.WriteLine($"[수신]: {message}"); } } |
✅ 결론
맞습니다. TCP 수신 측에서는 한 줄씩 정확하게 들어온다는 보장을 할 수 없기 때문에, 반드시 **“패킷 구분자 기반 분리 및 누적 버퍼 처리”**가 필요합니다.
아래는 C#으로 작성된 파일 A0011.dat의 각 줄을 읽어, 각 줄 뒤에 0x0D 0x0A 0xFF 구분자를 붙여 TCP로 송신하는 프로그램입니다.
📌 요약
항목내용
인코딩 방식 | Encoding.ASCII 사용하여 1바이트 문자로 정확하게 송신 |
줄 처리 방식 | File.ReadLines()로 메모리 효율적으로 한 줄씩 처리 |
패킷 구분자 | 각 줄 끝에 [0x0D, 0x0A, 0xFF] 붙여 송신 |
예외 처리 | 연결 실패나 파일 문제 예외 처리 포함 |
📌 참고 사항
- 파일 경로가 실행 파일과 같은 디렉토리에 있는 A0011.dat입니다.
- 서버 IP/포트를 실제 환경에 맞게 변경하세요 (127.0.0.1:5000 은 로컬 테스트용).
- 줄바꿈 없이 저장된 문자열도 정상적으로 송신됩니다.
- 한 줄씩 0x0D 0x0A 0xFF를 끝에 붙여 거래소 송신 포맷을 모방합니다.
✅ 동작 개요
- 텍스트 파일 A0011.dat을 한 줄씩 읽음
- 각 줄을 Encoding.UTF8로 변환하여 TCP 서버로 송신
- 각 라인의 끝에 0x0D 0x0A 0xFF 바이트를 붙여 송신
- TCP 서버의 IP와 포트는 사용자가 설정 가능
'통신 > CHAT.GPT' 카테고리의 다른 글
TCP/IP 통신에서 송신 측이 보낸 "헤더조차 수신하지 못하는 경우"도 충분히 발생할 수 있습니다. (2) | 2025.07.10 |
---|---|
TCP는 바이트 스트림 프로토콜/패킷 단위가 아니라 연속된 바이트 흐름 (0) | 2025.07.09 |
TCP/IP 송신.수신 프로그램관계.질문(1) (2) | 2025.07.09 |
Oracle DB 직접 조회 방식 (TCP/IP 소켓 통한 DB 조회)/REDIS (3) | 2025.06.25 |
HTS나 MTS클라이언트 & 서버(TCP/IP - REDIS) (0) | 2025.06.24 |