.NET Socket 통신과 Disconnect 이벤트

[목차(도우미)]
.NET Socket 통신에서 Disconnect이벤트는 언제 발생하나

FD_CLOSE이벤트가 WSA 라이브러리에 발생하는 것을 가지고 이벤트 처리하던 방식이 .NET의 SOCKET에서는 특별히 BeginDisconnect를 언제 수행해야하는지에 관한 MSDN문헌을 찾을 수 없었다. 그러다가 외국 블로그 사이트에서 BeginRead의콜백함수에서 0바이트 버퍼 수신을 계기로 절단을 판단해야 한다는 글을 찾을 수 있었다.
URL:
http://nitoprograms.blogspot.com/2009/06/using-socket-as-connected-socket.html

MSDN URL:
http://msdn.microsoft.com/en-us/library/fx6588te.aspx

WSA 라이브러리 내부에서 어떤 계기로 절단 이벤트를 통지했는지에 관한 근거를 찾을 수는 없지만 .NET프레임워크에서 Disconnect를 따로 이벤트 처리하지 않고 있다는 점을 종합해 볼 때 0바이트 수신을 계기로 절단 이벤트 통지를 구현해온 것으로 추측된다. 0바이트 수신을 특별케이스로 취급한다는 것이다. (0바이트인데 수신했다는 뜻이 절단을 의미하는 것으로 약속된 것으로 보인다)

아무튼 SOCKET 클래스를 사용하여 서버용 소켓 통신을 구현하려고 할 때 클라이언트의 절단 통지는 수신 버퍼사이즈를 통해 판단 할수 있다.
다음은 MSDN의 샘플 코드(VB.NET) bytesRead =0인 경우를 절단으로 판단해주었어야 한다. 즉 판단문을 추가하여 Disconnect 관련 처리를 구현하여야 한다.
  1.     Public Shared Sub ReadCallback(ByVal ar As IAsyncResult)
  2.         Dim content As String = String.Empty

  3.         ' Retrieve the state object and the handler socket
  4.         ' from the asynchronous state object.
  5.         Dim state As StateObject = CType(ar.AsyncState, StateObject)
  6.         Dim handler As Socket = state.workSocket

  7.         ' Read data from the client socket.
  8.         Dim bytesRead As Integer = handler.EndReceive(ar)

  9.         If bytesRead > 0 Then
  10.             ' There  might be more data, so store the data received so far.
  11.             state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead))

  12.             ' Check for end-of-file tag. If it is not there, read
  13.             ' more data.
  14.             content = state.sb.ToString()
  15.             If content.IndexOf("<EOF>") > -1 Then
  16.                 ' All the data has been read from the
  17.                 ' client. Display it on the console.
  18.                 Console.WriteLine("Read {0} bytes from socket. " + vbLf + " Data : {1}", content.Length, content)
  19.                 ' Echo the data back to the client.
  20.                 Send(handler, content)
  21.             Else
  22.                 ' Not all data received. Get more.
  23.                 handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state)
  24.             End If
  25.         End If
  26.     End Sub 'ReadCallback
by 금메달.아빠 on 2010. 10. 29. 01:46