На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Соблюдайте общие правила форума
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Указывайте точные версии Delphi и используемых сетевых библиотек.

Не приветствуется поднятие старых тем. Если ваш вопрос перекликается со старой темой, то для вопроса лучше создать новую тему, а старую указать в первом сообщении с описанием взаимосвязи.

Внимание:
попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Krid, user posted image Rouse_

Модераторы: Krid, Rouse_
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Разбиение пакетов TCP
    Добрый день!
    Использую связку TServer\ClientSocket (дефолтные из D2007) в неблокирующем режиме. Я подразумеваю, что инфа, отправленная одним вызовом sendText на одной из сторон, придёт полностью в буфере первого сработавшего onRead на противоположной стороне. Правильно ли такое предположение?
      Не совсем.
      Дело в том, что в TCP/UDP существует такое понятие как low water-mark
      Сокет готов для чтения, если выполнено одно из следующих условий:
      • Число байтов данных в приемном буфере сокета больше или равно текущему значению минимального количества данных low water-mark (может быть задано функцией setsockopt() с помощью опции сокета SO_RCVLOWAT) для приемного буфера сокета.
      Для сокетов TCP и UDP значение low water-mark по умолчанию равно 1.
      Грубо говоря, как только в буфер сокет придет ОДИН байт - выставится событие FD_READ
      PS
      Кстати, ПАКЕТОВ в TCP нет. Порции данных, формируемые модулем ТСР, носят название "сегмент" :)
      Сообщение отредактировано: Oleg2004 -
        unconnected
        сетевые vcl компоненты без понимания протоколов - зло!
        Под борландом/эмбаркадеро лучше всего работать либо напрямую с асинхронными сокетами, либо пользовать дот нет.
        Первое дает возможность реализовать то, что ты хочешь, достаточно эффективно. Второе - быстро.
        Ну и да, тебе нужно поверх твоих инкубаторских компонентов обозначать неким маркером начало и конец передачи, ибо тцп сокет - он просто дает тебе поток где ты можешь отправлять байты хоть по пять-десять и получать сотнями или тысячами и наоборот, поэтому для тсокетклиентов и прочего мусора - нет как такового события onRead.
        Теоретически, ты можешь отправить сотню байт одним send и получить 99 событий onRead, вычитывая по одному байту.

        Твоя проблема - типичная для новичков, запустивших дэлфи и думающих, что там в стандартных компонентах все есть и ничего не надо делать.
        Но на этапе реализации сетевых протоколов всех юзеров ожидает "облом петрович" - всю эту палитру vlc, на которую так все уповают, нужно выбросить. И делать все по уму (хотя "Винда" и "по уму" понятия из разных галактик).
        Т.е. Если ты хочешь отправить текст и получить текст - тебе нужно перебираться протоколом повыше (почитай о семиуровневой модели https://ru.wikipedia.org/wiki/%D0%A1%D0%B5%...D0%BB%D1%8C_OSI) - работать не на уровне TCP (третий, он же транспортный), а уже на уровне четвертом, он же уровень приложений, скажем, по HTTP. Ну или как вариант, напиши свой протокол, где у тебя будет обозначено начало передачи, конец передачи, и для своего протокола создай визуальную компоненту и поделись ею со всеми на форуме )))))
          Цитата nemez @

          1.поэтому для тсокетклиентов и прочего мусора - нет как такового события onRead.
          2.Теоретически, ты можешь отправить сотню байт одним send и получить 99 событий onRead, вычитывая по одному байту.

          Первое противоречит второму и наоборот. :)
            Цитата Oleg2004 @

            имеется ввиду к пониманию автором самого события onRead, а именно
            Цитата
            Я подразумеваю, что инфа, отправленная одним вызовом sendText на одной из сторон, придёт полностью в буфере первого сработавшего onRead на противоположной стороне.

            поэтому еще раз акцентирую внимание - предположение неправильное, ибо инфа, отправленная одним вызовом sendText, может вызвать несколько вызовов onRead, и наоборот, можно несколько раз вызвать sendText, и получить одно событие onRead.
            onRead - не обязательно получение буфера, отправленного одним send, но получение либо фрагментов из одного send, либо вообще склейки буферов, отправленного несколькими send, либо если повезет, то можно и получить буфер отправленный send.

            Поток, он и в Африке поток. TCP дает именно поток, но оно него не контролирует и не должно. Поток контролируют на уровень выше.
              Цитата nemez @
              поэтому еще раз акцентирую внимание - предположение неправильное, ибо инфа, отправленная одним вызовом sendText, может вызвать несколько вызовов onRead, и наоборот, можно несколько раз вызвать sendText, и получить одно событие onRead.
              onRead - не обязательно получение буфера, отправленного одним send, но получение либо фрагментов из одного send, либо вообще склейки буферов, отправленного несколькими send, либо если повезет, то можно и получить буфер отправленный send.

              Безусловно поток читать можно и по байтику, и сотнями...
              Но событие на сокете, фиксирующее прибытие low water-mark значения, всегда возникает в модулях TCP/UDP, во всех операционках - типа FD_READ. А уж сколько раз оно еще может возникнуть...так это дело пятое...
              А в остальном согласен... :yes:
                ключевое слово -
                Цитата
                во всех операционках

                винду нельзя рассматривать как полноценную ось, это скорей недооперационка с недоFD_READ.
                взято здесь:
                https://msdn.microsoft.com/en-us/library/wi...v=vs.85%29.aspx

                Цитата
                SO_RCVLOWAT
                A socket option from BSD UNIX included for backward compatibility. This option sets the minimum number of bytes to process for socket input operations.
                This option is not supported by the Windows TCP/IP provider.

                Как видим по тексту, оно в винде болтается только для обратной совместимости с BSD UNIX, на самом деле оно для мебели и и в реалиях не работает. Об этом утверждают сами мелкомягкие. К ним, на самом деле, особых претензий нет. Но это уже сути вопроса касается не напрямую.
                  Цитата nemez @
                  Как видим по тексту, оно в винде болтается только для обратной совместимости с BSD UNIX, на самом деле оно для мебели и и в реалиях не работает.

                  Ну как тут не согласиться...
                  К сожалению, некоторые фичи сетевого программирования, доступные в *nix, для винды все еще экзотика.
                  Да, опция может и не поддерживаться, но само дефолтное значение в 1 байт - оно таки есть.
                  И как только карточка перешлет в буфер приема сокета 1 байт, событие FD_READ взведется.
                    Если передача не блокируемая, то передача идёт потоком и о пакетах можно забыть. Блокировка как раз и синхранизирует принятие пакета.
                    А про low water-mark можете забыть это устаревшая технология. Так как большенство устройств работают пакетами или блоками, а не побайтно. Так быстрее. На микро-контроллёре это ещё рентабельно. Некоторые никсы её тоже эмулируют для совместимости.
                      Цитата Pavia @
                      А про low water-mark можете забыть это устаревшая технология. Так как большенство устройств работают пакетами или блоками, а не побайтно.

                      Интересное заявление.
                      С каких таких пор протокол ТСР стал устаревшей технологией???
                      И куда подевался его таймер запросов (persistence timer), описанный в спецификации протокола?
                      Цитата
                      Пусть получатель, приостановивший передачу данных путем посылки сегмента с нулевым размером окна, отправляет своему партнеру сообщение о возобновлении работы, но тот его не получает. Если подтверждения теряются, то это в принципе может привести к тупиковой ситуации, когда обе стороны будут дожидаться прихода подтверждений. В таком случае, чтобы продолжить передачу, отправитель с периодом, задаваемым таймером, посылает запросы с одним байтом данных.

                      Именно для этого и установлен low water-mark равный одному байту...
                      А блоки-пакеты на устройствах - протокол не волнуют...
                        Цитата
                        С каких таких пор протокол ТСР стал устаревшей технологией???

                        ну так протокол старый, как дерьмо мамонта.
                        Правильно его называют, time consumption protocol.
                        Он разрабатывался десятки лет назад, когда сеть была коаксиальной, и любая непонятка для него - congestion. Дрочилово с размером окна, которое работает непойми как и кем и когда реализованное. Он реально устарел и фактически не работает по человечески ни на беспроводных каналах, ни на линиях связи между континентами;
                        Парк этих древних протоколов пора менять. Они не удовлетворяют коммуникационным возможностям на сегодняшний день.
                          Цитата nemez @
                          ну так протокол старый, как дерьмо мамонта.

                          Ну да, таблице умножения лет наверно так тысяч пять...дерьмо мамонта. :D

                          Цитата nemez @
                          Он разрабатывался десятки лет назад, когда сеть была коаксиальной, и любая непонятка для него - congestion. Дрочилово с размером окна, которое работает непойми как и кем и когда реализованное. Он реально устарел и фактически не работает по человечески ни на беспроводных каналах, ни на линиях связи между континентами;

                          К сетевому и канальному уровням транспортник ТСР не имеет никакого отношения.
                          Да, протокол старый - но работает до сих пор однозначно эффективно - единственный протокол, в котором внутри реализован механизм 100% гарантии передачи.
                          Так что альтернативы просто нет.
                          И не будет я думаю еще лет 100 :D.
                          А механизм скользящего окна - просто люкс... :yes:
                          Единственный протокол, в котором внутри реализован механизм регулирования скорости передачи.
                          Имхо... :)
                            Цитата Oleg2004 @
                            В таком случае, чтобы продолжить передачу, отправитель с периодом, задаваемым таймером, посылает запросы с одним байтом данных.

                            В RFC такого нет. Там написано что с приходом первого байта возобновляется передача. А это может быть и байт и пакет. Грубо говоря достаточно проверки вида Length >0. Но линуксойды ввели порог. Понятно что в какой-то реализации это имеет смысл. Но гораздо лучше делать это пакетами.

                            Добавлено
                            http://pubs.opengroup.org/onlinepubs/79087...setsockopt.html
                            Цитата
                            SO_RCVLOWAT
                            Sets the minimum number of bytes to process for socket input operations. The default value for SO_RCVLOWAT is 1. If SO_RCVLOWAT is set to a larger value, blocking receive calls normally wait until they have received the smaller of the low water mark value or the requested amount. (They may return less than the low water mark if an error occurs, a signal is caught, or the type of data next in the receive queue is different than that returned, e.g. out of band data). This option takes an int value. Note that not all implementations allow this option to be set.
                              А я-то раньше полагался на один пакет (отправка) <=> один onRead, пока в логах не увидел страанное деело.. :) Сделал деление на пакеты на уровне своих данных. Ещё, наверное, хорошо было бы нумеровать их, ведь гарантии порядка прихода вроде как тоже нет.
                                Цитата Олег2004 @
                                однозначно эффективно - единственный протокол, в котором внутри реализован механизм 100% гарантии передачи.

                                не единственный, существует целый ворох таковых на базе УДП, УДТ например. Там тоже гарантирована 100% доставка. Тот же тфтп и иже с ним, поэтому говорить о том, что этот протокол единственный, не приходится.
                                Об эффективности ТСР - отдельная песня. Из которой слов не выкинешь

                                user posted image

                                Добавлено
                                Цитата Oleg2004 @
                                И не будет я думаю еще лет 100 .
                                А механизм скользящего окна - просто люкс...
                                Единственный протокол, в котором внутри реализован механизм регулирования скорости передачи.

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

                                На сегодняшний день есть коммерческие реализации сетевых протоколов, позволяющие работать более эффективно по сравнению с TCP. Специально для беспроводных сетей, вайфаев, лте, работающих с джиттером, задержкой и потерями. Хочешь хорошую передачу даты - плати. Или юзай дедушку TCP.
                                Сообщение отредактировано: nemez -
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0.0845 ]   [ 15 queries used ]   [ Generated: 25.08.26, 15:45 GMT ]