private void EndWriteTcp(IAsyncResult ar) { lock (this.outgoingPackets) { try { this.stream.EndWrite(ar); BinaryEventHandler h = this.OnSent; if (!(h is null)) { try { h(this, (byte[])ar.AsyncState); } catch (Exception ex) { Debug.WriteLine(ex.Message); Debug.WriteLine(ex.StackTrace.ToString()); } } if (!(this.outgoingPackets.First is null)) { byte[] Packet = this.outgoingPackets.First.Value; this.outgoingPackets.RemoveFirst(); this.stream.BeginWrite(Packet, 0, Packet.Length, this.EndWriteTcp, Packet); } else { this.writing = false; } }
internal void UdpDatagramReceived(object Sender, UdpDatagramEventArgs e) { if (this.encapsulatePackets) { LinkedList <KeyValuePair <ushort, byte[]> > LostPackets = null; byte[] FirstPacket = null; ushort FirstPacketNr = 0; ushort PacketNr; byte[] Packet; byte[] Data = e.Data; int Len = Data.Length; int Pos = 0; int PacketLen; int Offset; byte b; lock (this.udpReceiveLock) { while (Pos < Len) { b = Data[Pos++]; PacketLen = (b & 127); Offset = 7; while (Pos < Len && (b & 128) != 0) { b = Data[Pos++]; PacketLen |= (b & 127) << Offset; Offset += 7; } if (Pos + 2 > Len) { break; } PacketNr = Data[Pos++]; PacketNr |= (ushort)(Data[Pos++] << 8); if (Pos + PacketLen > Len) { break; } Packet = new byte[PacketLen]; Array.Copy(Data, Pos, Packet, 0, PacketLen); Pos += PacketLen; if ((short)(PacketNr - this.lastReceivedPacket) > 0) { if (FirstPacket == null) { FirstPacket = Packet; FirstPacketNr = PacketNr; } else { if (LostPackets == null) { LostPackets = new LinkedList <KeyValuePair <ushort, byte[]> >(); } LostPackets.AddFirst(new KeyValuePair <ushort, byte[]>(PacketNr, Packet)); // Reverse order } } } if (FirstPacket != null) { this.lastReceivedPacket = FirstPacketNr; } } BinaryEventHandler h = this.OnReceived; if (h != null) { if (LostPackets != null) { foreach (KeyValuePair <ushort, byte[]> P in LostPackets) { try { h(this, P.Value); } catch (Exception ex) { Events.Log.Critical(ex); } } } if (FirstPacket != null) { try { h(this, FirstPacket); } catch (Exception ex) { Events.Log.Critical(ex); } } } } else { byte[] Data = e.Data; int Len = Data.Length; byte[] Packet = new byte[Len]; Array.Copy(Data, 0, Packet, 0, Len); BinaryEventHandler h = this.OnReceived; if (h != null) { try { h(this, Packet); } catch (Exception ex) { Events.Log.Critical(ex); } } } }
private async void BeginReadTcp() { BinaryEventHandler h = null; int Pos; int NrLeft; byte b; try { while (!this.disposed) { int NrRead = await this.stream.ReadAsync(this.incomingBuffer, 0, BufferSize); if (NrRead <= 0 || this.disposed) { this.Closed(); break; } else { this.lastTcpPacket = DateTime.Now; this.resynchCallback = null; if (this.encapsulatePackets) { Pos = 0; while (Pos < NrRead) { switch (this.readState) { case 0: b = this.incomingBuffer[Pos++]; this.packetSize |= (b & 127) << this.offset; this.offset += 7; if ((b & 128) == 0) { this.packetBuffer = new byte[this.packetSize]; this.packetPos = 0; this.readState = 1; } break; case 1: NrLeft = NrRead - Pos; if (NrLeft > this.packetSize - this.packetPos) { NrLeft = this.packetSize - this.packetPos; } Array.Copy(this.incomingBuffer, Pos, this.packetBuffer, this.packetPos, NrLeft); Pos += NrLeft; this.packetPos += NrLeft; if (this.packetPos >= this.packetSize) { h = this.OnReceived; if (h != null) { try { h(this, this.packetBuffer); } catch (Exception ex) { Log.Critical(ex); } } this.readState = 0; this.packetSize = 0; this.offset = 0; this.packetBuffer = null; } break; default: Pos = NrRead; break; } } } else { this.packetSize = NrRead; this.packetBuffer = new byte[this.packetSize]; Array.Copy(this.incomingBuffer, 0, this.packetBuffer, 0, NrRead); h = this.OnReceived; if (h != null) { try { h(this, this.packetBuffer); } catch (Exception ex) { Log.Critical(ex); } } } } } } catch (Exception) { this.Closed(); } }
/// <summary> /// Sends a packet to the peer at the other side of the TCP connection. Transmission is done asynchronously and is /// buffered if a sending operation is being performed. /// </summary> /// <param name="Packet">Packet to send.</param> /// <param name="Callback">Optional method to call when packet has been sent.</param> public async void SendTcp(byte[] Packet, EventHandler Callback) { if (this.disposed) { return; } try { byte[] EncodedPacket = this.EncodePacket(Packet, false); lock (this.outgoingPackets) { if (this.writing) { this.outgoingPackets.AddLast(new QueuedItem(EncodedPacket, Callback)); return; } else { this.writing = true; this.lastTcpPacket = DateTime.Now; } } while (EncodedPacket != null) { await this.stream.WriteAsync(EncodedPacket, 0, EncodedPacket.Length); if (this.disposed) { return; } BinaryEventHandler h = this.OnSent; if (h != null) { try { h(this, EncodedPacket); } catch (Exception ex) { Log.Critical(ex); } } if (Callback != null) { try { Callback(this, new EventArgs()); } catch (Exception ex) { Log.Critical(ex); } } lock (this.outgoingPackets) { if (this.outgoingPackets.First != null) { QueuedItem Item = this.outgoingPackets.First.Value; EncodedPacket = Item.Packet; Callback = Item.Callback; this.outgoingPackets.RemoveFirst(); } else { this.writing = false; EncodedPacket = null; Callback = null; } } } } catch (Exception) { this.Closed(); } }
public StatCallback(BinaryEventHandler e) { _handleEvent = e; }