Мультиплексирование с сокетами Беркли

У меня есть реализация веб-сервера HTTP / 1.1, которую я написал на C ++ с использованием сокетов Berkeley. Я ищу реализацию поддержки HTTP / 2.0 (или SPDY), которая позволяет мультиплексировать запросы и ответы:

Уровень двоичного кадрирования в HTTP / 2.0 обеспечивает полное мультиплексирование запросов и ответов, позволяя клиенту и серверу разбивать HTTP-сообщение на независимые кадры, чередовать их, а затем повторно собирать их на другом конце.

У меня следующий вопрос; как я могу включить мультиплексирование запросов и ответов типа HTTP / 2.0 (или SPDY) с моей уже существующей программой HTTP / 1.1, которая пишет с использованием Berkeley Socket API? Возможно, упомянутое мультиплексирование кадров, поддерживаемое HTTP / 2.0 (или SPDY), уже обрабатывается существующими механизмами в стеке TCP / IP, или?

Уточнение:

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


person Community    schedule 13.07.2014    source источник
comment
SPDY - это другой протокол. Что вы ищете в ответе, кроме реализации протокола?   -  person janm    schedule 13.07.2014
comment
@janm В стеке TCP / IP существует множество типов мультиплексирования, я ищу решение, позволяющее реализовать тот тип мультиплексирования запросов / ответов, который поддерживает HTTP / 2.0 (и SPDY). Остальная часть протокола HTTP / 2.0 (или SPDY) не входит в объем рассматриваемого вопроса. Спасибо.   -  person    schedule 13.07.2014
comment
SPDY не входит в стек TCP / IP, он выше TCP, традиционно считается прикладным протоколом. Его управление и фреймы данных задокументированы в проекте спецификации. Вы реализуете мультиплексирование, реализуя протокол. Вы читали черновик протокола?   -  person codenheim    schedule 13.07.2014
comment
@mrjoltcola Да, я знаю, что HTTP / 2.0 (или SPDY) не является частью стека TCP / IP, и я никогда не предполагал, что это так. Не могли бы вы добавить ссылку на упомянутый вами протокол реализации протокола мультиплексирования? -TIA   -  person    schedule 13.07.2014
comment
Прошу прощения за недоумение, но последнее предложение в вашем посте, похоже, подразумевает именно это. Во всяком случае, посмотри мой ответ.   -  person codenheim    schedule 13.07.2014


Ответы (1)


Нет, стек TCP не обрабатывает ничего из этого, потому что SPDY не является частью стека TCP / IP, он выше TCP, который традиционно считается протоколом приложения. Его управление и фреймы данных задокументированы в проекте спецификации. Вы реализуете мультиплексирование, реализуя протокол. Стек TCP ничего не знает о HTTP или SPDY.

Короче говоря, SPDY состоит из кадров в рамках одного TCP-соединения, которые, помимо прочего, включают довольно простые заголовки с идентификатором сеанса и длиной кадра. Вы должны реализовать это для мультиплексирования. Вы должны иметь возможность реализовать все это с помощью стандартного кода сокета с поддержкой SSL / TLS.

Насколько я знаю, это спецификация -

http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft2

person codenheim    schedule 13.07.2014
comment
Как насчет части мультиплексирования, при которой использует одно соединение для доставки несколько запросов и ответов параллельно, я не понимаю из спецификаций, как это реализовано в протоколе уровня приложения? Любые идеи? - person ; 13.07.2014
comment
@IngeHenriksen Он просто поддерживает соединение и отправляет другой запрос. Никакой загадки. - person user207421; 13.07.2014
comment
@IngeHenriksen Приведенная вами ссылка показывает, как SPDY позволяет нескольким потокам существовать одновременно, используя одно TCP-соединение. Это делается с помощью кадрирования SPDY, определяющего, какие данные какому потоку принадлежат. Путаница может возникнуть из-за термина «параллельный» - в одном TCP-соединении кадры из разных потоков должны появляться один за другим, но не требуется, чтобы один поток завершался до начала другого. - person janm; 13.07.2014
comment
Итак, вы читаете кадры по одному кадру по порядку, просматривая заголовок каждого кадра, чтобы узнать, к какому потоку он принадлежит, буферизуя / анализируя данные каждого кадра по мере необходимости. Когда вы достигнете последнего кадра запроса в данном потоке, обработайте буфер этого потока и отправьте ответ по мере необходимости, аналогичным образом формируя данные ответа параллельно с ответами других потоков. Вам необходимо реализовать параллельную обработку потоков, а не параллельную обработку кадров. Кадрирование необходимо сериализовать, чтобы кадры не перекрывались в каждом направлении. Отправить кадр для одного потока, отправить кадр из другого потока и т. Д. - person Remy Lebeau; 13.07.2014
comment
@RemyLebeau Итак, если при отправке не удалось отправить весь поток, сформированный за один раз, нужно ли мне снова перекомпилировать оставшиеся байты потока и, возможно, добавить номер детали для блока? а на стороне получателя анализирует данные, удаляя каждый кадр, чтобы получить поток? - person a man in love; 11.04.2018
comment
@amaninlove, если отправка действительно не удалась, состояние TCP-соединения не определено, поэтому единственный жизнеспособный вариант - закрыть соединение и начать с нового соединения. Но если при отправке просто отправляется меньше байтов, чем запрошено, то да, вы должны повторно отправить оставшиеся байты, и нет, вам не нужно повторно кадрировать данные. Просто завершите отправку кадра, который вы начали отправлять. Не начинайте отправку нового кадра, пока не закончится предыдущий. То же самое на принимающей стороне. Прочтите полный кадр, сколько бы чтений ни потребовалось для завершения, затем обработайте кадр, затем прочитайте следующий кадр и т. Д. - person Remy Lebeau; 11.04.2018
comment
@Remy Lebeau Спасибо за ваш ответ. Однако то, что вы объяснили, связано с проблемой блокировки заголовка линии. Я указывал на проблему, при которой несколькими командами можно обмениваться по одному соединению одновременно, не дожидаясь завершения данных для запуска другого запроса, например, вы запрашиваете загрузку файла, в то время как в то же время может быть выдается с помощью таймера. Теперь очевидно, что это проблема с одним TCP-соединением, потому что данные могут перекрываться друг с другом. Каково идеальное решение этой проблемы при использовании одного TCP-соединения? - person a man in love; 12.04.2018
comment
@amaninlove Перечитайте то, что я уже комментировал ранее, это относится к мультиплексированию нескольких команд через одно TCP-соединение. Мультиплексирование требует кадрирования, и каждый кадр должен быть отправлен / получен полностью перед отправкой / получением следующего кадра, не перекрывайте кадры. В вашем примере у вас будет отдельный фрейм для запроса ping, ответа ping, запроса файла и каждого фрагмента данных файла. Вы можете смешивать кадры для разных команд (отправить запрос ping, прочитать фрагмент файла, прочитать ответ ping, прочитать фрагмент файла и т. Д.), Просто не перекрывайте кадры, иначе вы их испортите. - person Remy Lebeau; 12.04.2018
comment
@Remy Lebea Да, но разве данные не чередуются? я имею в виду, представьте, что сервер отправляет запрос на загрузку файла, путь находится во фрейме, теперь предположим, что таймер выпустил пинг между ними, на стороне получателя, когда получатель вызывает WSARecv, он может получить часть загрузки файла, другой WSARecv может получить часть команды ping или частичную команду ping, а затем другую часть команды загрузки файла. Я лично пробовал это, и данные перепутались. - person a man in love; 12.04.2018
comment
@amaninlove, что означает, что вы неправильно управляете своими чтениями / отправками. Иди, перечитай мои предыдущие комментарии еще раз внимательнее, я устал повторяться. Вы НЕ МОЖЕТЕ делать то, что описали. Вы ДОЛЖНЫ отправить фрейм полностью (это может потребовать многократной записи) перед отправкой нового фрейма. Вы ДОЛЖНЫ получить кадр полностью (для этого может потребоваться несколько чтений) перед получением следующего кадра. Если отправитель хочет отправить новый кадр, в то время как предыдущий кадр все еще занят отправкой, ему придется отложить новый кадр до более позднего времени. Поместите его в очередь, а затем отправьте кадры из очереди по порядку. - person Remy Lebeau; 12.04.2018
comment
@amaninlove TCP - это поток байтов, в нем нет понятия границ сообщений. Вы сами несете ответственность за управление границами сообщений. КАЖДЫЙ разработчик сокетов TCP должен правильно решать эту проблему. Мультиплексирование обрабатывает это, заключая сообщения в кадры, позволяя получателю знать, где заканчивается один кадр и начинается следующий. Если WSARecv получает части из нескольких кадров, вы несете ответственность за буферизацию данных и их разбиение на границах кадра. В противном случае используйте библиотеку, которая обрабатывает это за вас. - person Remy Lebeau; 12.04.2018
comment
Спасибо за ваше объяснение, это то, что мне не хватало. Приказ. Я знаю о задержке кадра и очереди, хотя в отдельном подключении это не нужно. Я думал, что мы можем отправлять данные, подобные тем, о которых я думал, и что то, что я понял о HTTP / 2, было неверным. Я смотрел твои ответы, и ты выглядишь очень профессионально. Я не мог задать вопрос, потому что мой аккаунт забанен. Приносим извинения за возможные неудобства. - person a man in love; 12.04.2018
comment
@amaninlove Я не мог задать вопрос, потому что моя учетная запись заблокирована - вероятно, для этого есть веская причина. Если вы не согласны с этим, спросите об этом у админов. - person Remy Lebeau; 12.04.2018