RESPONSE-CHAT.GPT/DEEP.SEEK
RESPONSE-CHAT.GPT/DEEP.SEEK

REQUEST)
거래소 주식 TCP 데이타는 회원사들이 100% 일방적으로 수신만 합니다. 거래소는 일방적으로 송신만 합니다. 그럼 회원사들이 사용하는 수신TCP프로그램을 작성하고 싶습니다. 데이타의 구분자는 3개의 딜리미터로 구분됩니다. 0x0a,0a0d,0xff입니다. c#으로 회원사 수신프로그램을 작성해주세요

RESPONSE-CHAT.GPT)

using System;
using System.Net;
u

sing System.Net.Sockets;

using System.Text;
using System.Threading;

class TcpServer
{
    private const int Port = 12345; // 서버 포트
    private TcpListener tcpListener;
    private bool isRunning;

    public TcpServer()
    {
        tcpListener = new TcpListener(IPAddress.Any, Port);
        isRunning = true;
    }

    public void Start()
    {
        tcpListener.Start();
        Console.WriteLine("TCP 서버가 시작되었습니다.");

        while (isRunning)
        {
            try
            {
                // 클라이언트 연결 대기
                var tcpClient = tcpListener.AcceptTcpClient();
                Console.WriteLine("클라이언트 연결됨.");

                // 클라이언트에서 데이터를 수신하는 작업 수행
                Thread clientThread = new Thread(() => HandleClient(tcpClient));
                clientThread.Start();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"오류: {ex.Message}");
            }
        }
    }

    private void HandleClient(TcpClient tcpClient)
    {
        NetworkStream stream = tcpClient.GetStream();
        byte[] buffer = new byte[1024];
        StringBuilder sb = new StringBuilder();

        while (true)
        {
            try
            {
                int bytesRead = stream.Read(buffer, 0, buffer.Length);
                if (bytesRead == 0)
                {
                    break; // 연결 종료
                }

                // 받은 데이터를 문자열로 변환
                sb.Append(Encoding.ASCII.GetString(buffer, 0, bytesRead));

                // 딜리미터에 맞춰 데이터 분리
                string data = sb.ToString();
                string[] messages = SplitByDelimiters(data);

                foreach (string message in messages)
                {
                    if (!string.IsNullOrEmpty(message))
                    {
                        Console.WriteLine($"수신된 메시지: {message}");
                    }
                }

                // 남은 데이터를 다시 설정
                sb.Clear();
                sb.Append(data.Substring(data.LastIndexOf(messages[messages.Length - 1]) + messages[messages.Length - 1].Length));
            }
            catch (Exception ex)
            {
                Console.WriteLine($"오류: {ex.Message}");
                break;
            }
        }

        tcpClient.Close();
        Console.WriteLine("클라이언트 연결 종료.");
    }

    private string[] SplitByDelimiters(string input)
    {
        // 3개의 딜리미터에 따라 데이터를 분리합니다.
        var delimiters = new string[] { "\x0A", "\x0D\x0A", "\xFF" };
        var messages = input;

        // 딜리미터를 기준으로 데이터를 분리
        foreach (var delimiter in delimiters)
        {
            messages = messages.Replace(delimiter, "\n"); // 구분자를 줄바꿈 문자로 바꿔서 Split
        }

        return messages.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
    }

    public void Stop()
    {
        isRunning = false;
        tcpListener.Stop();
    }

    static void Main(string[] args)
    {
        TcpServer server = new TcpServer();
        server.Start();
    }
}

 


REQUEST)
거래소 주식 TCP 데이타는 회원사들이 100% 일방적으로 수신만 합니다. 거래소는 일방적으로 송신만 합니다. 그럼 회원사들이 사용하는 수신TCP프로그램을 작성하고 싶습니다. 데이타의 구분자는 3개의 딜리미터로 구분됩니다. 0x0a,0a0d,0xff입니다. c#으로 회원사 수신프로그램을 작성해주세요

RESPONSE-DEEP.SEEK)

using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        string serverIP = "거래소서버IP"; // 거래소 서버 IP 주소
        int port = 12345; // 거래소 서버 포트 번호

        TcpClient client = new TcpClient(serverIP, port);
        NetworkStream stream = client.GetStream();

        byte[] buffer = new byte[1024];
        StringBuilder dataReceived = new StringBuilder();

        while (true)
        {
            int bytesRead = stream.Read(buffer, 0, buffer.Length);
            if (bytesRead == 0)
            {
                // 서버와의 연결이 끊어졌을 경우
                break;
            }

            string chunk = Encoding.ASCII.GetString(buffer, 0, bytesRead);
            dataReceived.Append(chunk);

            ProcessReceivedData(dataReceived);
        }

        stream.Close();
        client.Close();
    }

    static void ProcessReceivedData(StringBuilder dataReceived)
    {
        string data = dataReceived.ToString();
        string[] delimiters = { "\x0a", "\x0d", "\xff" };

        // 데이터를 구분자로 분리
        string[] messages = data.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);

        foreach (string message in messages)
        {
            Console.WriteLine("Received: " + message);
        }

        // 처리된 데이터는 제거
        dataReceived.Clear();
    }
}

 

>정보분배.수신
c# (feat. DOT.NET)


rcv_windows_dotcode.cs
0.00MB



>dotnet new console -o NetPro
>dotnet build
>dotnet run -- 21111


'통신' 카테고리의 다른 글

소켓 프로그래밍(client,server)  (0) 2022.11.20

 

REQUEST)
회원사에서 수신만 해도 송신측으로 ACK신호가 가나요?

RESPONSE)
TCP 통신에서는 회원사가 데이터를 수신하기만 해도 자동으로 송신 측으로 ACK(확인 응답) 신호가 전송됩니다. 이는 TCP 프로토콜의 기본 동작 방식으로, 송신 측이 데이터가 성공적으로 전달되었는지 확인하는 데 사용됩니다.

어떻게 ACK가 동작하나요?

  1. 데이터 수신
    • 송신 측에서 데이터를 전송하면, 수신 측(회원사)은 이를 TCP 계층에서 먼저 처리합니다.
    • 애플리케이션에서 실제 데이터를 처리하지 않아도, TCP 계층에서 데이터를 수신한 후 자동으로 ACK를 생성합니다.
  2. ACK 전송
    • 수신 측 TCP 계층은 데이터 패킷이 손상되지 않았고 올바르게 도착했음을 송신 측에 알리기 위해 ACK 패킷을 송신합니다.
    • ACK에는 다음에 기대하는 **시퀀스 번호(Sequence Number)**가 포함됩니다.
  3. 회원사에서 처리 지연이 있어도 ACK는 즉시 발송
    • 회원사 애플리케이션에서 데이터 처리가 느리더라도, TCP 스택 자체는 데이터를 수신한 즉시 ACK를 보냅니다.
    • 하지만, 수신 버퍼가 가득 차거나 회원사 애플리케이션이 데이터를 읽지 않아 문제가 발생하면 송신 측에 영향을 줄 수 있습니다.

수신 측에서 ACK를 안 보내는 경우

ACK가 송신되지 않는 경우는 일반적으로 다음과 같은 상황에서 발생합니다:

  1. 수신 버퍼 오버플로우
    • 회원사 측에서 데이터를 읽지 않아 수신 버퍼가 가득 차면 TCP 윈도우 크기가 0으로 설정됩니다.
    • 이 경우, ACK는 송신되지만 송신 측은 데이터 전송을 일시 중단합니다.
  2. 네트워크 장애
    • ACK 패킷이 네트워크 문제로 인해 송신 측에 도달하지 못할 수 있습니다.
  3. 수신 측 시스템 장애
    • 수신 측 시스템이 과부하 상태거나 비정상적으로 동작하면 ACK가 생성되지 않거나 늦게 송신될 수 있습니다.

요약

회원사가 데이터를 수신하기만 하면 TCP 스택이 자동으로 ACK를 송신합니다. 하지만 회원사 측의 애플리케이션이 데이터를 처리하지 못해 수신 버퍼가 가득 차거나 네트워크 상태가 불안정하면 송신 측의 데이터 전송이 영향을 받을 수 있습니다. 이를 방지하려면 수신 측 시스템의 안정성과 처리 속도를 보장하는 것이 중요합니다.

REQUEST)
수신 측인 회원사에서 데이터를 처리하는 과정에서 딜레이가 발생하면(?)

RESPONSE)
TCP 통신에서 거래소가 증권 정보 데이터를 일방적으로 송신하고, 수신 측인 회원사에서 데이터를 처리하는 과정에서 딜레이가 발생하면 다음과 같은 현상이 벌어질 수 있습니다.

1. TCP 윈도우 크기 축소 (Flow Control)

  • TCP는 수신 측의 데이터 처리 속도에 따라 송신 속도를 조절합니다.
  • 회원사 쪽에서 데이터를 처리하지 못하고 수신 버퍼가 꽉 차면, 수신 측은 송신 측에 윈도우 크기를 줄이라는 신호를 보냅니다.
  • 송신 측에서는 이를 인지하고 데이터 송신 속도를 줄입니다.
  • 최악의 경우, 수신 측이 윈도우 크기 = 0 신호를 보내면 송신 측은 데이터를 전송하지 못하고 대기 상태에 빠집니다.

2. 송신 측의 데이터 큐 축적

  • 회원사에서 데이터를 처리하지 못해 ACK 패킷이 늦게 도착하면, 송신 측의 데이터 큐에 전송 대기 데이터가 점점 쌓이게 됩니다.
  • 이로 인해 송신 측의 메모리 사용량 증가 또는 송신 애플리케이션의 지연 문제가 발생할 수 있습니다.
  • 데이터 큐가 한계에 도달하면 송신 애플리케이션은 데이터를 더 이상 보내지 못하거나 연결이 끊어질 수 있습니다.

3. 연결 끊김 가능성 (Timeout)

  • TCP는 패킷 전송 후 수신 측으로부터 ACK를 받지 못하면 재전송을 시도합니다.
  • 재전송을 여러 번 시도해도 응답이 없으면, 연결이 타임아웃되어 종료될 수 있습니다.
  • 특히 네트워크가 불안정하거나 회원사 시스템이 과부하 상태라면 이런 상황이 빈번히 발생할 수 있습니다.

4. 증권 정보의 지연 전달

  • 회원사가 데이터를 실시간으로 처리하지 못하면 증권 정보가 적시에 전달되지 않을 수 있습니다.
  • 이는 주식 매매와 같은 실시간 거래에 큰 영향을 미쳐 시장의 신뢰성을 해칠 가능성이 있습니다.

해결 방안

  1. 회원사 데이터 처리 속도 최적화
    • 데이터 처리 로직을 개선하거나 병렬 처리 등을 통해 처리 속도를 높입니다.
  2. TCP 윈도우 크기 및 버퍼 관리 최적화
    • 수신 측에서 TCP 버퍼 크기를 늘리거나 송신 측에서 데이터 송신 속도를 조절합니다.
  3. UDP 프로토콜 사용 검토
    • TCP의 신뢰성 보장을 위한 제어 메커니즘이 문제라면, 신뢰성보다는 속도가 중요한 경우 UDP를 사용하는 것도 고려할 수 있습니다.
  4. 애플리케이션 레벨의 큐 처리
    • 데이터 처리 지연이 발생하더라도 송수신 사이에 임시 버퍼(큐)를 두어 데이터를 효율적으로 관리합니다.

이와 같은 현상은 네트워크 환경, 시스템 성능, 애플리케이션 설계 방식에 따라 다르게 나타날 수 있으니, 구체적인 원인 분석이 필요합니다.

i5-3570 CPU (3.40GHz) / i5-10400 CPU (2.9GHz) 성능에 따른 모델변경

하드웨어 성능때문에 TCP패킷처리 못할경우, 아키텍쳐를 변경해서 처리가능

1번 장비에서 처리하지 못할경우에는 아키텍쳐 모델을 변경해본다.
현재 2기가에 해당되는 레디스메모리를 활용하면 큐와 같은 역할을 담당할수 있기때문에 레디스로 일단 전송후에 다른쓰래드에서 레디스에서 데이타를 꺼내서 처리하는 방법을 사용한결과 장비성능이 낮더라도 모두 처리가 가능할수 있음을 알수 있다.



1. Intel(R) Core(TM) i5-3570 CPU @ 3.40GHz


ARCHITECTURE MODEL1 : FAIL
ARCHITECTURE MODEL2 : SUCC

2. 인텔 / 코어i5-10세대 / 코멧레이크S / i5-10400 (2.9GHz) 

ARCHITECTURE MODEL1 : SUCC
ARCHITECTURE MODEL2 : SUCC

-TCT ESTATE DATA SEND
-REDIS MONITOR

-REDIS.TICK.SERVER
-DEBUGGER

 

TCP의 흐름 제어/Ack/Console/Multi File Send/Recv/Thread/Windows/
TCP의 흐름 제어/Ack/Console/Multi File Send/Recv/Thread/Windows/
TCP의 흐름 제어/Ack/Console/Multi File Send/Recv/Thread/Windows/

 

SEND(Console)

send.cs
0.01MB

 

RECV(Console)

recv.cs
0.01MB

TCP(Transmission Control Protocol)은 원활한 통신을 위해 전송하는 데이터 흐름을 제어하고 네트워크의 혼잡 상태를 파악해서 대처하는 기능을 프로토콜 자체에 포함하고 있다.
만약 TCP가 이런 기능들을 제공해주지 않는다면 개발자가 일일히 데이터를 어떤 단위로 보낼 것인지 정의해야하고, 패킷이 유실되면 어떤 예외처리를 해야하는 지까지 신경써야하기 때문에 TCP가 제공해주는 이러한 기능들 덕분에 우리는 온전히 상위 레이어의 동작에만 집중할 수 있는 것이다.
보통 TCP의 전송 제어 방법은 전송되는 데이터의 양을 조절하는 흐름 제어, 통신 도중에 데이터가 유실되거나 잘못된 데이터가 수신되었을 경우 대처하는 방법인 오류 제어, 네트워크 혼잡에 대처하는 혼잡 제어로 나누어진다.
물론 TCP 같은 전송 계층의 프로토콜을 어플리케이션 레이어에서 활동하는 개발자가 건드릴 일은 많이 없다. 그러나 혹시라도 이 부분에서 뭔가 문제가 발생했을 경우, TCP가 어떤 식으로 작동하는지 모른다면 고치는 건 둘째치고 원인 파악조차 하지 못하는 슬픈 상황이 발생할 수 있으므로 여러모로 알아두는 것이 좋다고 생각한다. (더불어 야근도 따라올 것이다)
그런 의미에서 이번 포스팅에서는 TCP의 흐름 제어 기법들과 오류 제어 기법들에 대한 이야기를 한번 해보려고 한다.

TCP의 흐름 제어

송신 측과 수신 측이 서로 데이터를 주고 받을 때, 여러가지 요인에 따라 이 두 친구들의 처리 속도가 달라질 수 있다. 이때 데이터를 받는 수신 측의 처리 속도가 송신 측보다 빠른 경우는 사실 별 문제가 없다.
주는 족족 빠르게 처리해주니 딱히 문제될 것이 없는 것이다. 그러나 수신 측의 처리 속도보다 송신 측이 더 빠른 경우 문제가 생긴다.
송신 측과 수신 측은 모두 데이터를 저장할 수 있는 버퍼를 가지고 있다. 이때 수신 측이 자신의 버퍼 안에 있는 데이터를 처리하는 속도보다 송신 측이 데이터를 전송하는 속도가 더 빠르다면, 당연히 수신 측의 버퍼는 언젠가 꽉 차버릴 것이기 때문이다.
수신 측의 버퍼가 꽉 찬 상태에서 도착한 데이터는 더 이상 담아둘 공간이 없기 때문에 폐기 처분된다. 물론 이런 상황에서는 송신 측이 다시 데이터를 보내주기는 하겠지만, 데이터 전송이라는게 네트워크 환경에 따라 변수가 워낙 많은 작업이기 때문에 사실 이 작업을 줄일 수 있으면 줄이는 것이 가장 좋다.
그래서 송신 측은 수신 측의 데이터 처리 속도를 파악하고 자신이 얼마나 빠르게, 많은 데이터를 전송할 지 결정해야한다. 이것이 바로 TCP의 흐름 제어인 것이다.
수신 측은 자신이 처리할 수 있는 데이터의 양을 의미하는 윈도우 크기(Window Size)를 자신의 응답 헤더에 담아서 송신 측에게 전해주게 되고, 송신 측은 상대방에게 데이터를 보낼 때 이 윈도우 크기와 네트워크의 현재 상황을 참고해서 알맞은 양의 데이터를 보냄으로써 전체적인 데이터의 흐름을 제어하게 된다.

1. Stop and Wait
Stop and Wait 방식은 이름 그대로 상대방에게 데이터를 보낸 후 잘 받았다는 응답이 올 때까지 기다리는 모든 방식을 통칭하는 말이다. 이때 데이터를 받는 수신 측은 잘 받았어!와 못 받았어... 등의 대답을 해주게 되는데, 수신 측이 어떤 대답을 해주냐에 따라 사용할 수 있는 오류 제어 방법이 나눠지기도 한다.
Stop and Wait로 흐름 제어를 할 경우의 대원칙은 단순히 상대방이 응답을 하면 데이터를 보낸다이기 때문에 구현 자체도 간단하고 개발자가 어플리케이션의 작동 원리를 파악하기도 쉬운 편이다.
기본적인 ARQ(Automatic Repeat Request)를 구현한다고 생각해보면, 수신 측의 윈도우 크기를 1 byte로 설정하고 처리 가능 = 1, 처리 불가능 = 0과 같은 식으로 대충 구현해도 돌아가기는 하기 때문이다.
하지만 서로 처리 가능, 처리 불가능 정도의 의미만 주고받는 방식은 간단한만큼 비효율적이라고 할 수도 있다. 왜냐하면 송신 측은 자신이 직접 데이터를 보내봐야 이 데이터를 수신 측이 처리할 수 있는지 알 수 있기 때문이다. 쉽게 말해서 이런 기초적인 Stop and Wait 방식은 그냥 될 때까지 주구장창 보내는 방식이라고 봐도 무방하다.
그런 이유로 Stop and Wait 방식을 사용하여 흐름 제어를 할 경우에는, 이런 비효율성을 커버하기 위해 이런 단순한 구현이 아닌 여러가지 오류 제어 방식을 함께 도입해서 사용한다.

2. Sliding Window

방금 알아본 바와 같이 Stop and Wait를 사용하여 흐름 제어를 하게 되면 비효율적인 부분이 있기 때문에, 오늘날의 TCP는 특별한 경우가 아닌 이상 대부분 슬라이딩 윈도우(Sliding Window) 방식을 사용한다.
슬라이딩 윈도우는 수신 측이 한 번에 처리할 수 있는 데이터를 정해놓고 그때그때 수신 측의 데이터 처리 상황을 송신 측에 알려줘서 데이터의 흐름을 제어하는 방식이다.
Stop and Wait과 여러 가지 차이점이 있겠지만, 
사실 가장 큰 차이점은 송신 측이 수신 측이 처리할 수 있는 데이터의 양을 알고 있다는 점이다. 
이 정보를 알고 있기 때문에 굳이 수신 측이 처리 가능이라는 대답을 일일히 해주지 않아도 데이터를 보내기 전에 이게 처리될 지 어떨지 어느 정도 예측이 가능하다는 말이다.

 

 

패킷의 흐름과 오류를 제어하는 TCP | Evans Library (evan-moon.github.io)

 

패킷의 흐름과 오류를 제어하는 TCP

은 원활한 통신을 위해 전송하는 데이터 흐름을 제어하고 네트워크의 혼잡 상태를 파악해서 대처하는 기능을 프로토콜 자체에 포함하고 있다.

evan-moon.github.io

 

 

 

TCP의 흐름 제어/Ack/Stop and Wait>File Send/Recv/Windows/Guage/Thread/
TCP의 흐름 제어/Ack/Stop and Wait>File Send/Recv/Windows/Guage/Thread/
TCP의 흐름 제어/Ack/Stop and Wait>File Send/Recv/Windows/Guage/Thread/

Send하는 파트에서 Thread 활용시에 다중 데이타를 송신/수신할수 있다.
Send하는 파트에서 Thread 활용시에 다중 데이타를 송신/수신할수 있다.
Send하는 파트에서 Thread 활용시에 다중 데이타를 송신/수신할수 있다.

TCP(Transmission Control Protocol)은 원활한 통신을 위해 전송하는 데이터 흐름을 제어하고 네트워크의 혼잡 상태를 파악해서 대처하는 기능을 프로토콜 자체에 포함하고 있다.
만약 TCP가 이런 기능들을 제공해주지 않는다면 개발자가 일일히 데이터를 어떤 단위로 보낼 것인지 정의해야하고, 패킷이 유실되면 어떤 예외처리를 해야하는 지까지 신경써야하기 때문에 TCP가 제공해주는 이러한 기능들 덕분에 우리는 온전히 상위 레이어의 동작에만 집중할 수 있는 것이다.
보통 TCP의 전송 제어 방법은 전송되는 데이터의 양을 조절하는 흐름 제어, 통신 도중에 데이터가 유실되거나 잘못된 데이터가 수신되었을 경우 대처하는 방법인 오류 제어, 네트워크 혼잡에 대처하는 혼잡 제어로 나누어진다.
물론 TCP 같은 전송 계층의 프로토콜을 어플리케이션 레이어에서 활동하는 개발자가 건드릴 일은 많이 없다. 그러나 혹시라도 이 부분에서 뭔가 문제가 발생했을 경우, TCP가 어떤 식으로 작동하는지 모른다면 고치는 건 둘째치고 원인 파악조차 하지 못하는 슬픈 상황이 발생할 수 있으므로 여러모로 알아두는 것이 좋다고 생각한다. (더불어 야근도 따라올 것이다)
그런 의미에서 이번 포스팅에서는 TCP의 흐름 제어 기법들과 오류 제어 기법들에 대한 이야기를 한번 해보려고 한다.

TCP의 흐름 제어

송신 측과 수신 측이 서로 데이터를 주고 받을 때, 여러가지 요인에 따라 이 두 친구들의 처리 속도가 달라질 수 있다. 이때 데이터를 받는 수신 측의 처리 속도가 송신 측보다 빠른 경우는 사실 별 문제가 없다.
주는 족족 빠르게 처리해주니 딱히 문제될 것이 없는 것이다. 그러나 수신 측의 처리 속도보다 송신 측이 더 빠른 경우 문제가 생긴다.
송신 측과 수신 측은 모두 데이터를 저장할 수 있는 버퍼를 가지고 있다. 이때 수신 측이 자신의 버퍼 안에 있는 데이터를 처리하는 속도보다 송신 측이 데이터를 전송하는 속도가 더 빠르다면, 당연히 수신 측의 버퍼는 언젠가 꽉 차버릴 것이기 때문이다.
수신 측의 버퍼가 꽉 찬 상태에서 도착한 데이터는 더 이상 담아둘 공간이 없기 때문에 폐기 처분된다. 물론 이런 상황에서는 송신 측이 다시 데이터를 보내주기는 하겠지만, 데이터 전송이라는게 네트워크 환경에 따라 변수가 워낙 많은 작업이기 때문에 사실 이 작업을 줄일 수 있으면 줄이는 것이 가장 좋다.
그래서 송신 측은 수신 측의 데이터 처리 속도를 파악하고 자신이 얼마나 빠르게, 많은 데이터를 전송할 지 결정해야한다. 이것이 바로 TCP의 흐름 제어인 것이다.
수신 측은 자신이 처리할 수 있는 데이터의 양을 의미하는 윈도우 크기(Window Size)를 자신의 응답 헤더에 담아서 송신 측에게 전해주게 되고, 송신 측은 상대방에게 데이터를 보낼 때 이 윈도우 크기와 네트워크의 현재 상황을 참고해서 알맞은 양의 데이터를 보냄으로써 전체적인 데이터의 흐름을 제어하게 된다.

1. Stop and Wait
Stop and Wait 방식은 이름 그대로 상대방에게 데이터를 보낸 후 잘 받았다는 응답이 올 때까지 기다리는 모든 방식을 통칭하는 말이다. 이때 데이터를 받는 수신 측은 잘 받았어!와 못 받았어... 등의 대답을 해주게 되는데, 수신 측이 어떤 대답을 해주냐에 따라 사용할 수 있는 오류 제어 방법이 나눠지기도 한다.
Stop and Wait로 흐름 제어를 할 경우의 대원칙은 단순히 상대방이 응답을 하면 데이터를 보낸다이기 때문에 구현 자체도 간단하고 개발자가 어플리케이션의 작동 원리를 파악하기도 쉬운 편이다.
기본적인 ARQ(Automatic Repeat Request)를 구현한다고 생각해보면, 수신 측의 윈도우 크기를 1 byte로 설정하고 처리 가능 = 1, 처리 불가능 = 0과 같은 식으로 대충 구현해도 돌아가기는 하기 때문이다.
하지만 서로 처리 가능, 처리 불가능 정도의 의미만 주고받는 방식은 간단한만큼 비효율적이라고 할 수도 있다. 왜냐하면 송신 측은 자신이 직접 데이터를 보내봐야 이 데이터를 수신 측이 처리할 수 있는지 알 수 있기 때문이다. 쉽게 말해서 이런 기초적인 Stop and Wait 방식은 그냥 될 때까지 주구장창 보내는 방식이라고 봐도 무방하다.
그런 이유로 Stop and Wait 방식을 사용하여 흐름 제어를 할 경우에는, 이런 비효율성을 커버하기 위해 이런 단순한 구현이 아닌 여러가지 오류 제어 방식을 함께 도입해서 사용한다.

 



>>>>보내는쪽에서의 개략소스)
>>>>보내는쪽에서의 개략소스)
>>>>보내는쪽에서의 개략소스)
>>>>보내는쪽에서의 개략소스)

while (true)
{
    while(true)
    {
        bytesSent = sender.Send(fileByte);
        bytesSent = sender.Receive(recvByte);

        string flagTxt = Encoding.UTF8.GetString(recvByte, 0, bytesSent);

        if (flagTxt == "no") continue;
        else if (flagTxt == "go") break;
    }
}

>>>>받는쪽에서 개략소스)
>>>>받는쪽에서 개략소스)
>>>>받는쪽에서 개략소스)
>>>>받는쪽에서 개략소스)

while (true)
{
    int sz = handler.Receive(bytes);

    if (sz == -1) break;
    else if (sz != PACKSZ) //제대로 받지를 못했다고 판단했을때에
    {
if (sz + cur < filesz) //실제로 마지막데이타도 아니라면
{
    handler.Send("no");
    continue;
}
    }

    cur += sz;

    handler.Send("go");

    if (cur > filesz) break;
    else if (filesz == cur) break;
}

 

TCP의 흐름 제어/Stop and Wait>File Recv/Windows/Guage/
TCP의 흐름 제어/Stop and Wait>File Recv/Windows/Guage/

Program.cs
0.00MB
ACKRcvFrm.cs
0.01MB
ACKRcvFrm.Designer.cs
0.06MB
AGauge.cs
0.06MB



TCP의 흐름 제어/ Stop and Wait>File Send/Windows/
TCP의 흐름 제어/ Stop and Wait>File Send/Windows/

 

ACKSndFrm.cs
0.01MB
ACKSndFrm.Designer.cs
0.00MB
Program.cs
0.00MB

+ Recent posts