private void SendBytesCb(IAsyncResult ar)
{
DebugUtils.DebugLog("SendBytesCb called.");
try
{
if (sock_ == null)
{
last_error_code_ = ErrorCode.kSendFailed;
last_error_message_ = "sock is null.";
DebugUtils.Log(last_error_message_);
return;
}
int nSent = sock_.EndSend(ar);
DebugUtils.DebugLog("Sent {0}bytes", nSent);
DebugUtils.Assert(nSent > 0, "Failed to transfer tcp messages.");
lock (sending_lock_)
{
// Removes any segment fully sent.
while (nSent > 0)
{
DebugUtils.Assert(sending_.Count > 0);
if (sending_[0].buffer.Count > nSent)
{
// partial data
DebugUtils.Log("Partially sent. Will resume.");
break;
}
else
{
DebugUtils.DebugLog("Discarding a fully sent message. ({0}bytes)",
sending_[0].buffer.Count);
// fully sent.
nSent -= sending_[0].buffer.Count;
sending_.RemoveAt(0);
}
}
while (sending_.Count > 0 && sending_[0].buffer.Count <= 0)
{
DebugUtils.DebugLog("Remove empty buffer.");
sending_.RemoveAt(0);
}
// If the first segment has been sent partially, we need to reconstruct the first segment.
if (nSent > 0)
{
DebugUtils.Assert(sending_.Count > 0);
ArraySegment<byte> original = sending_[0].buffer;
DebugUtils.Assert(nSent <= sending_[0].buffer.Count);
ArraySegment<byte> adjusted = new ArraySegment<byte>(original.Array, original.Offset + nSent, original.Count - nSent);
sending_[0].buffer = adjusted;
}
last_error_code_ = ErrorCode.kNone;
last_error_message_ = "";
SendUnsentMessages();
}
}
catch (ObjectDisposedException e)
{
DebugUtils.Log("BeginSend operation has been Cancelled.");
DebugUtils.DebugLog(e.ToString());
}
catch (Exception e)
{
last_error_code_ = ErrorCode.kSendFailed;
last_error_message_ = "Failure in SendBytesCb: " + e.ToString();
DebugUtils.Log(last_error_message_);
AddToEventQueue(OnFailure);
}
}