привет
Делаю я тут сокет сервер. Для приема/отправки сообщений использую свой протокол, такого типа
int PacketTypeId
int PacketLength
byte[] Data;
код для анализа raw socket data такой
public class BufferParser
{....
private readonly MemoryStream _stream = new MemoryStream(1024);
private readonly byte[] _buffer = new byte[1024];
public void Parse()
{
lock (_stream)
{
int step = 0;
int structLength = -1;
IParserStruct currentStruct = null;
//reset stream Position, After writing it points to the end of stream
_stream.Position = 0;
while (_stream.Position + 8 <= _stream.Length) //8 cause we need at least 8 bytes to start
{
if (step == 0)
{
//read Id - it must be always at first place
_stream.Read(_buffer, 0, 8); //8 bytes for StructId and its Length
int structId = BitConverter.ToInt32(_buffer, 0);
Type currentStructType;
if (!Structs.TryGetValue(structId, out currentStructType))
throw new BufferParserException(string.Format("Structure with ID = {0} is not supported.", structId));
currentStruct = (IParserStruct)Activator.CreateInstance(currentStructType);
//read struct Length
structLength = BitConverter.ToInt32(_buffer, 4);
step = 1;
continue;
}
if (step == 1)
{
if (currentStruct == null || structLength == -1)
throw new BufferParserException("Got to read the structure, but not created.");
if (structLength + _stream.Position <= _stream.Length)
{
_stream.Read(_buffer, 0, structLength);
currentStruct.ReadBytes(_buffer, 0);
//make an additional check to ensure struct was read OK. Not used in this version
//if (!currentStruct.CrcOk())
// throw new BufferParserException("Structure was read, but its CRC is wrong.");
//if is ok, raise the event that structure was read succesfully
StructRead(this, currentStruct);
//go read another structure
step = 0;
}
else
{
break; //nothing to read
}
}
}
if (step == 1)
_stream.Position -= 8;
int shiftBufferLength = (int)(_stream.Length - _stream.Position);
if (shiftBufferLength > 0)
{
_stream.Read(_buffer, 0, shiftBufferLength);
_stream.SetLength(0);
_stream.Seek(0, SeekOrigin.Begin);
_stream.Write(_buffer, 0, shiftBufferLength);
}
else
{
_stream.SetLength(0);
_stream.Seek(0, SeekOrigin.Begin);
}
}
}
у каждого клиента свой BufferParser, на данный момент всё работает нормально, но иногда приходят "плохие" данные и выбрасывается исколючение
BufferParserException, именно из этого и была создана
темаАвтор: Holms
Дата: 25.11.09
, никто не предполагал что такое исключение может быть и оно осталось не обработанным.
Щас всё нормально, но интересно как пишутся протоколы которые бы были устойчивы к непредвиденным данным. Блокировать плохие пока IP клиент не разрешает.
Может не стоить изобретать велосипед и есть что-то готовое уже?
Также искал "high-speed scalable TCP/IP server" ничего путного кроме как примеров чата не нашел. Подскажите что используете вы, трудно верится что все пишут свои велосипеды
Смотрел
ACE но показалось что оно слишком большое, да и учить другую библиотеку как-то не шибко охота
Спасибо
... << RSDN@Home 1.2.0 alpha 4 rev. 1253>>