비동기 통신 Begin~ 후 Callback에 End~를 왜 넣는가에 대하여

FGPRJS·2022년 5월 4일
0

C#의 소켓의 비동기 통신 중 Begin/End에 관한 고찰이다.


왜 Begin~ 하면 Callback에 End~를 넣는지?

다음 코드는 공식문서에서 제공하는 비동기 소켓 통신 예제이다.

public static void Read_Callback(IAsyncResult ar){
    StateObject so = (StateObject) ar.AsyncState;
    Socket s = so.workSocket;

    int read = s.EndReceive(ar);

    if (read > 0) {
            so.sb.Append(Encoding.ASCII.GetString(so.buffer, 0, read));
            s.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0,
                                     new AsyncCallback(Async_Send_Receive.Read_Callback), so);
    }
    else{
         if (so.sb.Length > 1) {
              //All of the data has been read, so displays it to the console
              string strContent;
              strContent = so.sb.ToString();
              Console.WriteLine(String.Format("Read {0} byte from socket" +
                               "data = {1} ", strContent.Length, strContent));
         }
         s.Close();
    }
}

BeginReceive 후에 등장하는 Callback에 EndReceive를 걸어놓았다.
그 후에 다시 BeginReceive를 하기 시작하는데, 왜 EndReceive를 해야 하는가?


공식 문서에서는 다음과 같이 기재되어있다.

  • The EndReceive method completes the asynchronous read operation started in the BeginReceive method.
  • EndReceive 메소드는 BeginReceive 함수로 시작한 비동기 읽기 작업을 완료합니다.
  • The EndReceive method will block until data is available.
    If you are using a connectionless protocol, EndReceive will read the first enqueued datagram available in the incoming network buffer.
    If you are using a connection-oriented protocol, the EndReceive method will read as much data as is available up to the number of bytes you specified in the size parameter of the BeginReceive method.
    If the remote host shuts down the Socket connection with the Shutdown method, and all available data has been received, the EndReceive method will complete immediately and return zero bytes.
  • EndReceive 메소드는 Data가 사용가능해질 때 까지 막을(Block) 것입니다.
    만약 비연결지향 프로토콜(UDP)을 사용한다면, EndReceive는 이후 네트워크 버퍼에서 사용가능한 첫번때 Queue된 데이터그램을 읽을 것입니다.
    만약 연결지향 프로토콜(TCP)을 사용한다면, EndReceive 메소드는 BeginReceive 메소드에 기재한 사이즈 파라미터의 값 만큼 읽으려고 할 것이다.
    만약 Remote 호스트가 Shutdown 메소드로 소켓 연결을 끊어버리고, 모든 가능한 데이터가 전송 되었다면, EndReceive 메소드는 EndReceive는 즉시 완료되며 0바이트의 데이터를 리턴한다.

즉, TCP를 통해 전달 받은 데이터를 완전히 읽을 수 있게 되기까지 기다려주는 함수로 볼 수 있다.

참고 사항

  • 공식문서에서 기재한 바는 "BeginReceive 메소드에 기재한 사이즈 파라미터의 값 만큼" 읽는다고 했다. 즉, 그 이상의 데이터를 쓴다고 해도 못읽는다. 그 값을 넘기지 않던지, 합칠 수 있는 알고리즘을 구성해야 한다.
profile
FGPRJS

0개의 댓글