질문)
송신하는 프로그램은 한줄씩 읽어서 보내지만, 수신하는측에서는 한줄씩 받는다고 보장할수 없겠죠? 수신측의 서버상태에 따라서, 한줄, 두줄, 세줄, 네줄 혹은 그 이상의 줄을 받을수도 있겠죠?

답변)

네, 정확하게 이해하셨습니다.

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와 포트는 사용자가 설정 가능




recv_distribution.cs
0.00MB
send_distribution.cs
0.00MB

+ Recent posts