Безопасный протокол для сокетов
От: Holms США  
Дата: 28.11.09 17:42
Оценка:
привет


Делаю я тут сокет сервер. Для приема/отправки сообщений использую свой протокол, такого типа

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>>
The life is relative and reversible.
Re: Безопасный протокол для сокетов
От: HowardLovekraft  
Дата: 28.11.09 18:35
Оценка:
Здравствуйте, Holms, Вы писали:

H>Может не стоить изобретать велосипед и есть что-то готовое уже?

Есть — это очень мягко говоря.

H>Подскажите что используете вы, трудно верится что все пишут свои велосипеды

Сейчас преимущественно WCF.
Re[2]: Безопасный протокол для сокетов
От: Holms США  
Дата: 28.11.09 21:14
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>Сейчас преимущественно WCF.

нее, только не WCF, пока не WCF, может позже...
... << RSDN@Home 1.2.0 alpha 4 rev. 1253>>
The life is relative and reversible.
Re: Безопасный протокол для сокетов
От: SHEMA  
Дата: 29.11.09 05:25
Оценка:
Здравствуйте, Holms, Вы писали:

H>Также искал "high-speed scalable TCP/IP server" ничего путного кроме как примеров чата не нашел. Подскажите что используете вы, трудно верится что все пишут свои велосипеды


H>Смотрел ACE но показалось что оно слишком большое, да и учить другую библиотеку как-то не шибко охота


Ну если смотрел ACE и не обязательно C#/.NET, то одним из популярных "high-speed scalable TCP/IP server" приложений является web-server. Берешь сорцы apache-a (лучше apache v.1, ранние версии) и смотришь ядро. Или юзаешь их фреймверк.

А вообще, конечно, давно пора забыть этот кошмар и юзать WCF
Re: Безопасный протокол для сокетов
От: Мизантроп  
Дата: 29.11.09 12:26
Оценка:
Здравствуйте, Holms, Вы писали:

H>иногда приходят "плохие" данные и выбрасывается исколючение BufferParserException,<...> , никто не предполагал что такое исключение может быть и оно осталось не обработанным.


А это как это? Если кто-то вставил его генерацию, значит всё-таки ожидал?

H>Щас всё нормально, но интересно как пишутся протоколы которые бы были устойчивы к непредвиденным данным. Блокировать плохие пока IP клиент не разрешает.

H>Может не стоить изобретать велосипед и есть что-то готовое уже?

А что Вы подразумеваете под "безопасный протокол"? Открыв форточку, нужно быть готовым, что со свежим воздухом в неё могут влететь и мухи, и смог Открыв порт, Вы никак не можете быть уверены, что к нему будут подключаться только "правильные" клиенты. И сколько бы надстроек между сокетным гнездом и Вашим кодом ни было, проверок Вам не избежать. Эти прослойки могут не пропустить к Вашему коду грубые ошибки, но только Вы сами в состоянии решить, какие данные или их комбинации допустимы в Вашем приложении в данной конкретной ситуации, а потому какого-то волшебства в данном аспекте ожидать не приходится.
"Нормальные герои всегда идут в обход!"
Re[3]: Безопасный протокол для сокетов
От: HowardLovekraft  
Дата: 29.11.09 16:07
Оценка:
Здравствуйте, Holms, Вы писали:

H>пока не WCF, может позже...

Мыши плакали, кололись?..
Из того, что еще есть в FCL — remoting, HttpListener.
Re[4]: Безопасный протокол для сокетов
От: Holms США  
Дата: 29.11.09 21:29
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>Мыши плакали, кололись?..

HL>Из того, что еще есть в FCL — remoting, HttpListener.
ну это становится ясно, начинаю изучать досконально WCF, вроде не такой страшный
... << RSDN@Home 1.2.0 alpha 4 rev. 1253>>
The life is relative and reversible.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.