Files
pokerth/console/src/lib/net/ReceiverThread.cs
T

125 lines
3.8 KiB
C#

/***************************************************************************
* 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 <http://www.gnu.org/licenses/>. *
***************************************************************************/
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<NetPacket>();
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<NetPacket> m_packetList;
private SenderThread m_sender;
private NetParser m_parser;
}
}