public bool SendPacket(RdpeudpPacket packet)
{
if (packet.sourceHeader.HasValue && AutoHandle)
{ // Deal with window area.
OutPacketState packetState = new OutPacketState();
packetState.Packet = packet;
packetState.Acknowledged = false;
DateTime endTime = DateTime.Now + this.SocketConfig.Timeout;
uint sendWindowsEndPos = SendWindowStartPosition + USendWindowSize;
while (DateTime.Now < endTime)
{
//If source sequence number is in send slide window, send the packet. Otherwise, wait a sendingInterval
if (!IsInSendWindow(packet.sourceHeader.Value.snSourceStart))
{
sendWindowLock.WaitOne(this.SocketConfig.sendingInterval);
}
else
{
break;
}
}
if (DateTime.Now > endTime)
{
// Time out.
return false;
}
packetState.SendTime = DateTime.Now;
lock (outPacketDic) outPacketDic[packet.sourceHeader.Value.snSourceStart] = packetState;
// Add RDPUDP_ACK_OF_ACKVECTOR_HEADER Structure if necessary
UpdateOutSnAckOfAcksSeqNum(packet);
}
byte[] data = PduMarshaler.Marshal(packet, false);
SendBytesByUDP(data);
// Update Last send time, which is used for keep alive timer
LastSendDiagramTime = DateTime.Now;
return true;
}