/// <summary> /// Fires when an error has occured; contains the exception and the errors operational severity /// </summary> private void OnSessionError(object owner, DtmErrorArgs args) { // in case window is closed; should call disconnect in a forms closing event if (_dtmServer.IsConnected) { Console.WriteLine(CON_TITLE + "Severity:" + (DtmErrorSeverityFlags)args.Severity + "Message: " + args.Message); } }
/// <summary> /// Sends a packet with increasing wait times. /// <para>After 4 attempts fires a SessionError.</para> /// </summary> /// /// <param name="PacketStream">The packet to send</param> private void Throttle(MemoryStream PacketStream) { int maxwait = 10; for (int i = 0; i < 4; i++) { try { Wait(maxwait); _clientSocket.SendAsync(PacketStream); break; } catch (CryptoSocketException ce) { SocketException se = ce.InnerException as SocketException; if (se.SocketErrorCode == SocketError.WouldBlock || se.SocketErrorCode == SocketError.IOPending || se.SocketErrorCode == SocketError.NoBufferSpaceAvailable) { // buffer is full maxwait *= 2; } else { // possible connection dropped, alert app if (SessionError != null) { DtmErrorArgs args = new DtmErrorArgs(ce, DtmErrorSeverityFlags.Connection); SessionError(this, args); } } } } // all attempts have failed if (maxwait > 160) { // possible connection dropped, alert app if (SessionError != null) { DtmErrorArgs args = new DtmErrorArgs(new SocketException((int)SocketError.HostUnreachable), DtmErrorSeverityFlags.Connection); SessionError(this, args); } } }
private void Transmit(DtmPacketFlags PacketType, short PacketFlag, long OptionFlag = 0, MemoryStream Payload = null) { lock (_sndLock) { long pldLen = Payload == null ? 0 : Payload.Length; // create a new packet: packet flag, payload size, sequence, and state flag MemoryStream pktStm = new DtmPacketStruct(PacketType, pldLen, _sndSequence, PacketFlag, OptionFlag).ToStream(); // add payload if (Payload != null) { // copy to output pktStm.Seek(0, SeekOrigin.End); Payload.WriteTo(pktStm); pktStm.Seek(0, SeekOrigin.Begin); } // store in the file packet buffer _sndBuffer.Push(_sndSequence, pktStm); // increment file send counter _sndSequence++; // transmit to remote client if (_clientSocket.IsConnected) { try { _clientSocket.SendAsync(pktStm); } catch (CryptoSocketException ce) { SocketException se = ce.InnerException as SocketException; if (se.SocketErrorCode == SocketError.WouldBlock || se.SocketErrorCode == SocketError.IOPending || se.SocketErrorCode == SocketError.NoBufferSpaceAvailable) { // buffer is full, throttle down Throttle(pktStm); } else { // possible connection dropped, alert app if (SessionError != null) { DtmErrorArgs args = new DtmErrorArgs(ce, DtmErrorSeverityFlags.Connection); SessionError(this, args); } } } catch (Exception ex) { // possible connection dropped, alert app if (SessionError != null) { DtmErrorArgs args = new DtmErrorArgs(ex, DtmErrorSeverityFlags.Connection); SessionError(this, args); } } // notify app if (PacketSent != null) { PacketSent(this, new DtmPacketArgs((short)DtmTransferFlags.DataChunk, pldLen)); } } } }