private void ReceiveComplete(object sender, SocketAsyncEventArgs saea)
{
try
{
lock (_session)
{
// transBytes가 0이면 원격지 혹은 네트워크에 의해 연결이 끊긴 상태
int transBytes = saea.BytesTransferred;
if (transBytes == 0)
{
_session.Close(AegisResult.ClosedByRemote);
return;
}
_receivedBuffer.Write(transBytes);
while (_receivedBuffer.ReadableSize > 0)
{
// 패킷 하나가 정상적으로 수신되었는지 확인
int packetSize;
StreamBuffer tmpBuffer = new StreamBuffer(_receivedBuffer, _receivedBuffer.ReadBytes, _receivedBuffer.ReadableSize);
if (_session.PacketValidator == null ||
_session.PacketValidator(tmpBuffer, out packetSize) == false)
break;
try
{
// 수신 이벤트 처리 중 종료 이벤트가 발생한 경우
if (_session.Socket == null)
return;
// 수신버퍼에서 제거
_receivedBuffer.Read(packetSize);
// 수신처리(Dispatch)
StreamBuffer dispatchBuffer = new StreamBuffer(tmpBuffer, 0, packetSize);
SpinWorker.Dispatch(() =>
{
if (_responseSelector.Dispatch(dispatchBuffer) == false)
_session.OnReceived(dispatchBuffer);
});
}
catch (Exception e)
{
Logger.Err(LogMask.Aegis, e.ToString());
}
}
// 처리된 패킷을 버퍼에서 제거
_receivedBuffer.PopReadBuffer();
// ReceiveBuffer의 안정적인 처리를 위해 작업이 끝난 후에 다시 수신대기
WaitForReceive();
}
}
catch (SocketException)
{
_session.Close(AegisResult.ClosedByRemote);
}
catch (Exception e)
{
Logger.Err(LogMask.Aegis, e.ToString());
}
}