private void OnSendComplete(object sender, SocketAsyncEventArgs args)
{
// 비동기 완료 및 재진입 처리
if (args.SocketError != SocketError.Success)
{
HandleSocketError(args.SocketError);
return;
}
if (_issueCountFlag.Decrement())
{
ProcessClose();
return;
}
_sendOffset += args.BytesTransferred;
if (_sendOffset < _sendLength)
{
// Send 버퍼를 덜 보냈으면 나머지를 다시 전송 요청
if (!_issueCountFlag.Increment())
return;
IssueSend();
}
else if (_sendLargeBuffer != null)
{
// Large 모드일 때 Large 버퍼의 내용을 Send 버퍼에 복사해 전송 요청
if (!_issueCountFlag.Increment())
return;
int len = Math.Min(_sendLargeLength - _sendLargeOffset, _sendBuffer.Length);
Debug.Assert(len > 0, "It should be large enough");
Array.Copy(
_sendLargeBuffer.Value.Array,
_sendLargeBuffer.Value.Offset + _sendLargeOffset,
_sendBuffer, 0, len);
_sendLargeOffset += len;
if (_sendLargeOffset == _sendLargeLength)
_sendLargeBuffer = null;
_sendLength = len;
_sendOffset = 0;
IssueSend();
}
else
{
// 전송 패킷 큐에 대기중인 패킷이 있으면 꺼내서 전송
if (Interlocked.Decrement(ref _sendCount) > 0)
{
object packet;
while (_sendQueue.TryDequeue(out packet) == false)
{
}
if (packet != null)
StartSend(packet);
else
Close();
}
}
}