/*************************************************************************** * Copyright (C) 2008 by Lothar May * * * * This file is part of pokerth_console. * * pokerth_console is free software: you can redistribute it and/or * * modify it under the terms of the GNU Affero General Public License * * as published by the Free Software Foundation, either version 3 of * * the License, or (at your option) any later version. * * * * pokerth_console is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the * * GNU Affero General Public License along with pokerth_console. * * If not, see . * ***************************************************************************/ using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Net; using System.Net.Sockets; using System.IO; namespace pokerth_lib { class ReceiverThread : NetThread { const uint MaxPacketSize = 268; const uint MinPacketSize = 8; public ReceiverThread(NetworkStream stream, SenderThread sender, PokerTHData data, ICallback callback) : base(stream) { m_recBuf = new byte[8192]; m_recBufOffset = 0; m_packetList = new List(); m_sender = sender; m_parser = new NetParser(data, sender, callback); } protected override void Main() { while (!IsTerminateFlagSet()) { ReadFromStream(); ScanPackets(); ParsePackets(); } } protected void ReadFromStream() { if (NetStream.DataAvailable) m_recBufOffset += NetStream.Read(m_recBuf, m_recBufOffset, m_recBuf.Length - m_recBufOffset); else Thread.Sleep(15); } protected void ScanPackets() { bool packetFound; do { packetFound = false; if (m_recBufOffset >= MinPacketSize) { // Treat input buffer as memory stream. MemoryStream memStream = new MemoryStream(m_recBuf); BinaryReader r = new BinaryReader(memStream); int type = IPAddress.NetworkToHostOrder((short)r.ReadUInt16()); int size = IPAddress.NetworkToHostOrder((short)r.ReadUInt16()); if (m_recBufOffset >= size) { packetFound = true; if (size > MaxPacketSize) { // Ignore packets which are too long. m_recBufOffset -= size; } else { // Scan Packet. NetPacket packet = NetPacket.Create(type, size, r); if (packet != null) m_packetList.Add(packet); // Advance within buf. if (m_recBufOffset > size) { for (int i = size, j = 0; i < m_recBufOffset; i++, j++) { m_recBuf[j] = m_recBuf[i]; } m_recBufOffset -= size; } else m_recBufOffset = 0; } } } } while (packetFound); } protected void ParsePackets() { foreach (NetPacket p in m_packetList) { p.Accept(m_parser); } m_packetList.Clear(); } private byte[] m_recBuf; private int m_recBufOffset; private List m_packetList; private SenderThread m_sender; private NetParser m_parser; } }