/// <summary> /// Handles the reception of data on the socket. /// </summary> /// <param name="ar">Tne async result.</param> private void OnSockReceive(IAsyncResult ar) { lock (syncLock) { if (sock == null) { return; } sock.EndReceiveFrom(ar, ref recvEP); try { var packet = new NetTracePacket(); packet.SourceEP = (IPEndPoint)recvEP; packet.Read(recvBuf); recvQueue.Enqueue(packet); } catch { // Ignore packets that can't be parsed } sock.BeginReceiveFrom(recvBuf, 0, recvBuf.Length, SocketFlags.None, ref recvEP, onSockRecv, null); } }
/// <summary> /// Called periodically to extract queued packets and forward them /// onto the packet receive handler. /// </summary> /// <param name="o">Not used.</param> public void OnTimer(object o) { NetTracePacket[] packets; NetTracePacket packet; SourceInfo sourceInfo; string sourceID; string lastSourceID; ArrayList updated; // Extract the packets from the queue as quickly as possible while // under the lock to avoid losing packets due to TCP buffer overflow. lock (syncLock) { if (recvQueue.Count == 0) { return; } packets = new NetTracePacket[recvQueue.Count]; for (int i = 0; i < packets.Length; i++) { packets[i] = (NetTracePacket)recvQueue.Dequeue(); } } // Check all the packet sequence numbers against what is expected // for each source being tracked. If we find anything out of order, // we're going to insert warning packets into the packet array at the // position where the problem was detected. This code is optimized // for the situation where there is no problem (which should be the // common case). updated = null; lastSourceID = null; sourceInfo = null; for (int i = 0; i < packets.Length; i++) { packet = packets[i]; sourceID = packet.TraceOriginID; if (sourceID != lastSourceID) { sourceInfo = (SourceInfo)sources[sourceID]; if (sourceInfo == null) { // We haven't seen this source yet, so create a // record for it sourceInfo = new SourceInfo(sourceID, packet.PacketNum); sources.Add(sourceID, sourceInfo); } } if (sourceInfo.NextPacketNum > packet.PacketNum) { // Looks like an out-of-order or missing packet. Create the "updated" // array list, add all of the good packets up to this point, insert // an notification packet, and then continue searching for problems. updated = new ArrayList(packets.Length + 10); for (int j = 0; j < i; j++) { updated.Add(packets[j]); } updated.Add(new NetTracePacket(0, 0, "LillTek.NetTrace", 0, "***** Trace Error *****", "Dropped or out-of-order packet(s).", null)); updated.Add(packets[i]); lastSourceID = null; for (int j = i + 1; j < packets.Length; j++) { packet = packets[j]; sourceID = packet.TraceOriginID; if (sourceID != lastSourceID) { sourceInfo = (SourceInfo)sources[sourceID]; if (sourceInfo == null) { // We haven't seen this source yet, so create a // record for it sourceInfo = new SourceInfo(sourceID, packet.PacketNum); sources.Add(sourceID, sourceInfo); } } if (sourceInfo.NextPacketNum > packet.PacketNum) { updated.Add(new NetTracePacket(0, 0, "LillTek.NetTrace", 0, "***** Trace Error *****", "Dropped or out-of-order packet(s).", null)); } updated.Add(packets[j]); sourceInfo.NextPacketNum++; lastSourceID = sourceID; } break; } sourceInfo.NextPacketNum++; lastSourceID = sourceID; } if (updated != null) { packets = new NetTracePacket[updated.Count]; for (int i = 0; i < updated.Count; i++) { packets[i] = (NetTracePacket)updated[i]; } } // Report the new packets to the receive delegate. onReceive(packets); }
public void Log(string subsystem, int detail, string tEvent, string summary, string details) { if (tracePause) { return; } if (subsystem == null) { subsystem = string.Empty; } if (tEvent == null) { tEvent = string.Empty; } if (summary == null) { summary = string.Empty; } if (details == null) { details = string.Empty; } #if DEBUGLOG StringBuilder sb = new StringBuilder(1024); sb.Append("==========\r\n"); sb.AppendFormat(null, "Event: {0}\r\n", tEvent); sb.AppendFormat(null, "Summary: {0}\r\n\r\n", summary); sb.Append(details); if (!details.EndsWith("\r\n")) { sb.Append("\r\n"); } Debug.Write(sb.ToString()); #else NetTracePacket packet; byte[] buf; int cb; int traceDetail; lock (syncLock) { if ((!traceEnable.TryGetValue(subsystem.ToLowerInvariant(), out traceDetail) || detail > traceDetail) && (!traceEnable.TryGetValue("default", out traceDetail) || detail > traceDetail)) { return; } try { packet = new NetTracePacket(sourceID, packetNum++, subsystem, detail, tEvent, summary, details); buf = new byte[NetTracePacket.MaxPacket]; cb = packet.Write(buf); sock.SendTo(buf, cb, SocketFlags.None, traceEP); } catch { } } #endif }