Конференция "Начинающим" » Обмен пакетами между сервером и клиентом
 
  • Rembo (01.02.11 16:58) [0]
    Привет всем. Вопрос абстрактного характера.
    Реализовываю обмен данными (packed record) между сервером и клиентом на сокетах. Нужно слать много разных данных, иногда строки, иногда записи. Так вот как это лучше сделать чтоб по трафику экономней было? Учитывая что заранее не известно какая именно запись придет (Socket.Receivebuf(buff,buffsize) решил сделать запись с полями на все случаи жизни, некоторые из которых часто будут пустовать. Все ли я правильно делаю?
  • Slym © (01.02.11 17:02) [1]
    Rembo   (01.02.11 16:58)
    заранее не известно какая именно запись придет

    так сделай чтоб было известно - посылай длинну первым делом
    Socket.Receivebuf(Size,SizeOf(Size));
    Socket.Receivebuf(buff,Size);

  • Rembo (01.02.11 18:04) [2]
    Тоесть прям так в TForm1.SocketServer1ClientRead и написать? Допустить что если какие то данные пришли знач сначала обязательно размер идет? А если между получением размера и самих данных будет пауза - все ж покрошится разве нет?
  • Slym © (02.02.11 08:37) [3]
    Rembo   (01.02.11 18:04) [2]
    оно по любому покрошится, даже не надейся что все одним куском придет...
    оно норовит рассыпаться, а иногда наоборот слипнуться
    а ты как программист должен эти крохи собрать в буфер, а если слиплось разделить, благо порядок крошек правильный...
  • Anatoly Podgoretsky © (02.02.11 10:59) [4]

    > все ж покрошится разве нет

    Обязательно покрошится, рано или поздно.
  • Rembo (02.02.11 15:28) [5]
    Сейчас уже думаю что моя запись на все случаи жизни получается и проще и надежней...
    Изначально я собирался выделять каждому клиенту место для хранения его запросов (те самые записи), чтобы потом в цикле пробегать по всем клиентам и обрабатывать их запросы (игру делаю), но возник вопрос: сможет ли сокет принимать пакеты пока работает главный цикл? ServerType стоит stNonBlocking, или нужно установить stThreadBlocking и создавать каждому подключению по thread-у?
  • ! (02.02.11 18:12) [6]

    > Сейчас уже думаю что моя запись на все случаи жизни получается
    > и проще и надежней...


    Логичнее изначально передавать некоторую структуру с информацией о том, какого типа будут переданные данные, какого они размера и какой нить отличительный признак структуры поставить, а при необходимости можно расшить и в этой же структуре передавать контрольную сумму, либо другую информацию для проверки.


    typedef struct
    {
    char strSign[30];  // "@@THE_MY_GAME_STRUCT" - пример признака
    int nDataSize;
    int nDateType;
    }
    TDataInfo;

  • Сергей М. © (02.02.11 21:31) [7]

    > моя запись на все случаи жизни получается и проще и надежней


    Кроме одного случая, когда юзер выкинет твой софт в топку или, не дай бог, поколотит тебя за беспардонное и бездумное растранжиривание его, кровного юзерского, трафика, пустьт даже и безлимитного)


    > сможет ли сокет принимать пакеты пока работает главный цикл?


    Сокет-то сможет).. А вот юзеры, см. выше, выкинут или побьют. если ихние запросы к твоему серверу будут висеть без ответа, пока твой суперцикл мечется по куче запросов)
  • DVM © (02.02.11 23:29) [8]

    > чтобы потом в цикле пробегать по всем клиентам и обрабатывать
    > их запросы (игру делаю), но возник вопрос: сможет ли сокет
    > принимать пакеты пока работает главный цикл?

    у тебя клиентов миллиарды намечается? проход по циклу в миллион итераций занимает ничтожно малое время по сравнению с передачей данных по сети.
  • Rembo (03.02.11 00:25) [9]

    > Логичнее изначально передавать некоторую структуру с информацией
    > о том, какого типа будут переданные данные

    А если данные имеют примерно такой же размер как и эта структура?


    > Кроме одного случая, когда юзер выкинет твой софт в топку
    > или, не дай бог, поколотит тебя за беспардонное и бездумное
    > растранжиривание его, кровного юзерского, трафика, пустьт
    > даже и безлимитного)
    > Сокет-то сможет).. А вот юзеры, см. выше, выкинут или побьют.
    >  если ихние запросы к твоему серверу будут висеть без ответа,
    >  пока твой суперцикл мечется по куче запросов)


    Вопервых я еще не совсем представляю объем данных, возможно речь вообще ниочем. А на счет цикла, так я честно говоря даже не представляю как можно организовать по другому взаимодействие небольшого множества (порядка 100) клиентов с собсно игровым миром.
    Пока что у меня на уме вот что:
    Сервер отсылает клиенту 2 типа данных, первое это - текстовые строки (для чата), второе это объекты (новые и изменения старых) которые в данный момент видны игроку - это записи состоящие из чисел 1-4 байта, в сумме не более 20 байт скорее всего, в самом тяжелом случае - 100 объектов на экране минимум раз в секунду ~ 2-3KB/S, не считая текста, по моему не так много.
    Подскажите пожалуйста, норм я все продумал или где то принципиальные ошибки?
  • sniknik © (03.02.11 00:45) [10]
    > или где то принципиальные ошибки?
    > Сервер отсылает клиенту
    сервер принципиально работает по запросу от клиента, а не насильно ему данные пихает.
    в большинстве случаев данные клиенту не нужны, и когда запросов нет сервер "спит"... в общем никто не работает, но все довольны, т.к. работа таки идет... у тебя же получится, что все "в мыле", а толку ноль.
  • Rembo (03.02.11 00:55) [11]
    Как так? Вот взять игру мморпг: там стоишь ничего не делаешь, серверу ничего не шлешь, а если прибежит игрок другой, надо ж всем рассказать! Или ты имеешь в виду что клиент должен через какие то отрезки времени обращаться к серверу и получать текущую ситуацию?
  • Германн © (03.02.11 01:33) [12]

    > Rembo   (03.02.11 00:55) [11]
    >
    > Как так?

    Это он "не врубился" в ситуацию. Но ты сам виноват. Про игру нужно было сразу сказать.


    > Нужно слать много разных данных, иногда строки, иногда записи.
    >  Так вот как это лучше сделать чтоб по трафику экономней
    > было? Учитывая что заранее не известно какая именно запись
    > придет (Socket.Receivebuf(buff,buffsize) решил сделать запись
    > с полями на все случаи жизни, некоторые из которых часто
    > будут пустовать. Все ли я правильно делаю?
    >

    Про вариантные записи читал/слышал? Если нет, прочитай.
  • Rembo (03.02.11 01:53) [13]
    Ага, слышал, но использовать не довелось, честно говоря есть сомнения по это счету, пришел буфер, набор байт, неизвестно это вся структура пришла, или половина, а определить какой именно это тип мне кажется невозможно
  • Servy © (03.02.11 01:58) [14]

    > пришел буфер, набор байт, неизвестно это вся структура пришла,
    >  или половина


    SizeOf(TStruct) - константная величина, даже если структура вариантная. Что тут может быть неизвестно?
  • Германн © (03.02.11 02:52) [15]

    > Rembo   (03.02.11 01:53) [13]
    >
    > Ага, слышал, но использовать не довелось, честно говоря
    > есть сомнения по это счету, пришел буфер, набор байт, неизвестно
    > это вся структура пришла, или половина, а определить какой
    > именно это тип мне кажется невозможно

    Про тип тебе уже ответил аноним в [6]. Этот тип вполне может (а может быть и должен) быть частью передаваемой структуры.
    P.S. При передаче/приеме вариантные записи - наше всё! ИМХО.
  • Rembo (03.02.11 18:14) [16]

    > typedef struct
    > {
    > ...
    > int nDataSize;
    > ...
    > }TDataInfo;
    > вариантные записи
    > SizeOf(TStruct) - константная величина, даже если структура
    > вариантная
    > Этот тип вполне может (а может быть и должен) быть частью
    > передаваемой структуры.

    Извиняюсь, но что-то я совсем запутался, судя из цитат мне предложили сделать следующее:
    Вариативная запись с статическим полем TDataInfo с указанным размером и типом и динамической частью с данными указанного размера и типа
    принимается частично:
    Socket.Receivebuf(data,<длинна статической части записи>);


    далее уже остаток:
    Socket.Receivebuf(<буфер типа динамической части>,<размер динамической части>);


    Я правильно понял?
  • Slym © (04.02.11 10:55) [17]
    Rembo   (03.02.11 18:14) [16]
    [1] первый ответ о том и повествует
  • han_malign (04.02.11 15:15) [18]

    > с указанным размером и типом и динамической частью

    - это называется TLV(tag-length-value)

    открытый стандарт(см. BER):
    http://book.itep.ru/4/44/asn44132.htm

    но для начала советую посмотреть протокол mail.ru-агента
    (ICQ - не советую - та еще помойка обратной совместимости)
  • Сергей М. © (04.02.11 16:04) [19]

    > стоишь ничего не делаешь, серверу ничего не шлешь, а если
    > прибежит игрок другой, надо ж всем рассказать


    "Видишь суслика ? И я не вижу. А он есть !" (ДМБ)

    Это тебе только кажется что "серверу ничего не шлешь".
    На самом деле клиент в какой-то момент времени сказал серверу: если кто-то там куда-то будет "прибегать", извести меня об этом , ок ? Я жду извещений ..
    Сервер ничего не ответил. Ибо никто никуда не "бегал" в этот  момент. А вот когда кто-то там куда-то забегает, сервер тут же ответи: вон он побежал, лови его скорей !

    ))
  • sniknik © (04.02.11 16:31) [20]
    > Я жду извещений ..
    причем строго определенное время, не больше, а то, все клиенты уже давно по отвалились, а сервер все шлет и шлет...
  • Rembo (04.02.11 16:48) [21]
    А-а, ну я понял, тоесть клиент должен каждые допустим пол секунды напоминать о себе и в ответ получать текущую ситуацию, текст из чата и т.д?
  • Сергей М. © (04.02.11 16:57) [22]
    ну да, примерно так.

    запрос - ожидание ответа - получение ответа - обработка ответа
    запрос - ожидание ответа - получение ответа - обработка ответа
    запрос - ожидание ответа - получение ответа - обработка ответа
  • Anatoly Podgoretsky © (04.02.11 16:58) [23]
    > sniknik  (04.02.2011 16:31:20)  [20]

    Спаммер какой то, а не сервер.
  • Rembo (04.02.11 23:38) [24]

    > ну да, примерно так.

    А можно в общих чертах как в идеале должно быть? Игра то многопользовательская (даже очень), хотя бы с на тыщу игроков расчетом
  • Xapakupu (04.02.11 23:55) [25]
    >>А можно в общих чертах как в идеале должно быть? Игра то многопользовательская (даже очень), хотя бы с на тыщу игроков расчетом

    В идеале тебе следует нанять опытную команду по разработке игр. Это не в общих чертах, это для тебя единственно правильное решение.
  • Palladin © (05.02.11 04:42) [26]
    ... и не позорь святое, манагер, Рэмбо пишется как Rambo, а ты вечная бездарность
  • rAmbo (05.02.11 14:48) [27]
    Охохо, это я то менеджер? С тех пор как мой основной ник в 2005-м, пишу этот ник :D

    > В идеале тебе следует нанять опытную команду по разработке
    > игр. Это не в общих чертах, это для тебя единственно правильное
    > решение.

    Вот спасибо, наконец то первый нормальный ответ по теме, а я все думал, что ж я не так делаю? Вроде делфи запустил, по кнопка долблю, а игры все нет и нет! А если серьезно, то я думал о том чтоб не нанимать опытную команду, а воспользоватся их трудом, http://raknet.com/ очень серьезный пакет, но увы, заголовочных файлов нет для делфи. В общем было бы неплохо узнать, есть ли сетевые движки, которые я смог бы использовать если сабж не сумею как следует реализовать
 
Конференция "Начинающим" » Обмен пакетами между сервером и клиентом
Есть новые Нет новых   [134437   +29][b:0.001][p:0.001]