// ================= Send =================== static void SendLoop(RawClient client) { NetworkStream stream = client.client.GetStream(); try { while (client.Connected) { client.sendPending.Reset(); if (client.sendQueue.TryDequeueAll(out byte[][] messages)) { try { if (header == null) { header = new byte[4]; } if (payload == null) { payload = new byte[MaxBufferSize]; } int position = 0; for (int i = 0; i < messages.Length; ++i) { Utilities.IntToBytesBigEndianNonAlloc(messages[i].Length, header); Array.Copy(header, 0, payload, position, header.Length); Array.Copy(messages[i], 0, payload, position + header.Length, messages[i].Length); position += header.Length + messages[i].Length; } stream.Write(payload, 0, position); } catch (Exception exception) { Log.WriteNow("Send: stream.Write exception: " + exception); break; } } client.sendPending.WaitOne(); } } catch (ThreadAbortException) { } catch (ThreadInterruptedException) { } catch (Exception exception) { Log.WriteNow("SendLoop Exception On Client, reason: " + exception); } finally { stream.Close(); client.client?.Close(); } }
// =============== Setup ================== public Client(string ip, ushort port) { rawClient = new RawClient(ip, port); rawClient.OnConnect += InternalOnConnect; rawClient.OnDisconnect += InternalOnDisconnect; rawClient.OnPacket += ProcessData; Handlers = new List <Handler>(); }
// =============== Recv =================== static void ReceiveLoop(RawClient client) { NetworkStream stream = client.client.GetStream(); DateTime messageQueueLastWarning = DateTime.Now; try { client.OnConnect?.Invoke(); while (true) { if (header == null) { header = new byte[4]; } if (!stream.ReadExactly(header, 4)) { break; } int size = Utilities.BytesToIntBigEndian(header); if (size > MaxPacketSize) { Log.WriteNow("ReadMessageBlocking: possible allocation attack with a header of: " + size + " bytes."); break; } byte[] data = new byte[size]; if (!stream.ReadExactly(data, size)) { break; } #if SLEEPY_STATS client.stats.RecvBytesTotal += (ulong)data.Length; client.stats.RecvTotal++; #endif client.OnPacket(data, data.Length); } } catch (Exception exception) { Log.WriteNow("ReceiveLoop: finished receive function for Client, reason: " + exception); } finally { stream.Close(); client.client?.Close(); client.OnDisconnect?.Invoke(); } }