Просмотр полной версии : порядок передачи пакетов
i_am_kisly
31.03.2015, 16:53
Собственно у меня два вопроса:
1) Если я получил пакет от сервера обязательно ли сразу слать на него ответ, или можно передать какой-то другой, а затем послать ответ на пришедший пакет.
2) Вопрос архитектурный и напрямую зависит от первого:
Получается у меня есть два потока RxThread и TxThread: при использовании синхронных сокетов socket.Receive() блокирует RXThread до приема данных, когда данные пришли , блокируем поток TxThread парсим входные данные и отправляем ответ. После этого разблокируем TxThread и снова ждем данных. Данный подход жизнеспособен или нет ?
Я очень плохо разбираюсь в сетевом программировании, поэтому прошу помощи.
ПС: пробовал изучать исходники L2NET бота, код сильно фрагментирован и плохочитаемый.
ScythLab
31.03.2015, 18:29
Ты сейчас спрашиваешь относительно ла2, или просто пытаешься создавать свое независимое клиент-серверное приложение?
В большинстве случае нет смысла блокировать потоки, их единственно нужно синхронизировать при работе с общими данными.
i_am_kisly
31.03.2015, 18:38
относительно ла2 на примере некоторого абстрактного сферического oog бота в вакууме :) По существу есть что-нибудь ?
не знаю как здесь, в моем случае клиент мог получить большой кусок информации за один раз, где были бы слеплены несколько пакетов. следовательно программа должна была читать весь этот кусок до конца, а не первые 2 байта по определению id пакета и весь кусок считать как один пакет. то есть надо было каждый приход инфы гонять по циклу - а ровняется ли пакет всему куску? если нет, сдвигать маркер по куску до конца первого пакета и начинать читать второй.
то есть на практике, если в клиенте нет функционала по отслеживанию этого момента - то предположим сервер шлет инфу клиенту о движении танка и о выстреле танком, то клиент примет инфу что танк двигается, а вот выстрел может тупо не обработать если он придет в том - большом куске.
я думаю в л2пх этим моментом - что в одном куске инфы может быть несколько пакетов и объясняется что порой в листинге некоторые пакеты появляются оптом сразу штук 5 очень быстро. я думаю что инфа пришла оптом в одном куске информации, а л2пх разобрал её по пакетам и выдал как разные пакеты, пришедшие по очереди.
i_am_kisly
31.03.2015, 22:43
друг, учись выражать свои мысли. Мне пришлось прочитать три раза, чтобы понять что у тебя склеиваются пакеты. Мои вопросы, то совсем о другом.
Добавлено через 3 минуты
В большинстве случае нет смысла блокировать потоки, их единственно нужно синхронизировать при работе с общими данными.
У меня и так почти все переменные пишутся через lock{}.. или ты предлагаешь лочить сокет ?
Добавлено через 3 минуты
и кто-нибудь наконец обьясните : ответы на некоторые пришедшие с сервера пакеты имеют больший приоритет, чем пакеты инициированные клиентом? Или равноценны? Просто от этого зависит куда их ставить: в начало или конец очереди
ScythLab
31.03.2015, 23:40
Все пакеты равнозначны, все их ставишь в очередь и по порядку обрабатываешь, если пакет требует ответа, то отвечаешь на него и переходишь к обработке следующего пакета в очереди и т.д. Лочить нить не нужно, правильного lock вполне достаточно.
И если мы все же говорим про ла2, то могут быть нюансы защит (хотя конечно я могу путать), некоторые защиты отправляют свои данные для проверки подлинности клиента, вот если на этот пакет не ответить во время, то может быть принудительный дисконнект, но опять-таки повторюсь - могу перепутать, возможно сервер отваливался по таймауту, если не получал ответ на свой запрос.
Добавлено через 2 минуты
И вообще по поводу отправки данных, они все происходят в одной нити, так что возможно клиент вначале обрабатывает все полученные данные от сервера и только потом переходит к опросу мыши/клавы/учету макросов
i_am_kisly
01.04.2015, 01:55
Все пакеты равнозначны, все их ставишь в очередь и по порядку обрабатываешь, если пакет требует ответа, то отвечаешь на него и переходишь к обработке следующего пакета в очереди и т.д.
Мне кажется, что это lurkmore.to/Взаимоисключающие_параграфы
Если все пакеты la2 (без защит) равнозначны, то ответ на пакет становится в конец очереди. Но дальше ты пишешь, что ответ вставляется в начало очереди, а значит пакеты "ответов" имеют явный проритет. На лицо явное противоречие.
Нет никакого приоритета. Есть 2 пула. На прием и на отправку пакетов.
Читаешь очередной пакет. Обрабатываешь его. В случае необходимости добавляешь ответный пакет в конец очереди на отправку на сервер. Все.
Да и вообще там всего пару пакетов которые требуют какого то ответа серверу. NetPing и GGQuery, вроде и все.
i_am_kisly
01.04.2015, 02:04
Алилуйа ! Спасибо за внятное обьяснение
ScythLab
01.04.2015, 16:13
Мне кажется, что это lurkmore.to/Взаимоисключающие_параграфы
Если все пакеты la2 (без защит) равнозначны, то ответ на пакет становится в конец очереди. Но дальше ты пишешь, что ответ вставляется в начало очереди, а значит пакеты "ответов" имеют явный проритет. На лицо явное противоречие.В клиенте ла2 только одна очередь пакетов для входящих данных, они принимаются в отдельном потоке и складываются в очередь. Дальше в главном потоке в общем цикле происходит несколько действий:
1) обработка принятых пакетов;
2) обработка действий пользователя;
3) просчет и отрисовка игрового мира.
При обработке входящих пакетов данные вытаскиваются из очереди (надеюсь теперь мы уяснили что это за очередь?) и обрабатываются, если пакет требует ответа, то идет моментальный ответ (грубо говоря идет вызов wsock32.send), и переходим к следующему пакету пока очередь не опустеет.
Какая последовательность работы вышеуказанных блоков я не знаю.
По сути не сильно важно есть ли очередь на отправку пакетов обратно на сервер, так как в этом направлении пакетов очень мало и они все равно уходили бы почти моментально.
i_am_kisly
17.04.2015, 00:53
В общем попробовал изобразить что-то вроде вот этого:
http://f6.s.qip.ru/10tdQEdlU.png (http://shot.qip.ru/00H5tx-610tdQEdlU/)
В макете получается, а встраиваю в приложение и потоки уходят в рассинхрон. Да и опять же тяп-ляп. Может быть есть какой-то готовый фреймворк с блекджеком и очередями?
Добавлено через 4 минуты
Потом периодически сервер не отвечает на RequestAuthLogin. Ничего не меняю, запускаю повторно и нормально доходит до PlayOk. В чем может быть проблема ?
Отправка пакетов происходит в главном потоке приложения.
i_am_kisly
17.04.2015, 01:25
Почему? Смотри, я получаю пакет, кидаю в приемную очередь. Из очереди его вытягивает парсер, собственно парсит и кидает ответ в очередь на отправку. Отправляющий поток достает подготовленный пакет из очереди "на отправку" и отправляет. Если отправка пакета инициирована клиентом, то да главный поток через эвенты. Меня больше мучает вопрос почему L2J то отвечает на авторизацию, то нет.
Это вопрос к L2J. Попробуй в режиме отладки логин ядра сервера посмотреть почему он посылает лесом.
А данные из какого потока л2 реально что обрабатывает получены путем навешивания хуков на функции и вычисления threaid потока. При отправке threaid совпал с threaid главного потока окна.
Распакованные пакеты в очередь AddNetworkQue вызываются из другого потока, но весьма вероятно что их вытаскивание и разбор ведется все в том же главном потоке. С этим я думаю и связана эпическая тормознутость клиента л2, особенно при медленном скармливании ему большого объема серверных пакетов.
vBulletin® v3.6.11, Copyright ©2000-2024, Jelsoft Enterprises Ltd. Перевод: zCarot