PDA

Просмотр полной версии : порядок передачи пакетов


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 бота в вакууме :) По существу есть что-нибудь ?

SeregaZ
31.03.2015, 21:37
не знаю как здесь, в моем случае клиент мог получить большой кусок информации за один раз, где были бы слеплены несколько пакетов. следовательно программа должна была читать весь этот кусок до конца, а не первые 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 (без защит) равнозначны, то ответ на пакет становится в конец очереди. Но дальше ты пишешь, что ответ вставляется в начало очереди, а значит пакеты "ответов" имеют явный проритет. На лицо явное противоречие.

Yegor
01.04.2015, 02:01
Нет никакого приоритета. Есть 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), и переходим к следующему пакету пока очередь не опустеет.
Какая последовательность работы вышеуказанных блоков я не знаю.

Yegor
01.04.2015, 19:12
По сути не сильно важно есть ли очередь на отправку пакетов обратно на сервер, так как в этом направлении пакетов очень мало и они все равно уходили бы почти моментально.

i_am_kisly
17.04.2015, 00:53
В общем попробовал изобразить что-то вроде вот этого:
http://f6.s.qip.ru/10tdQEdlU.png (http://shot.qip.ru/00H5tx-610tdQEdlU/)
В макете получается, а встраиваю в приложение и потоки уходят в рассинхрон. Да и опять же тяп-ляп. Может быть есть какой-то готовый фреймворк с блекджеком и очередями?

Добавлено через 4 минуты
Потом периодически сервер не отвечает на RequestAuthLogin. Ничего не меняю, запускаю повторно и нормально доходит до PlayOk. В чем может быть проблема ?

Yegor
17.04.2015, 01:16
Отправка пакетов происходит в главном потоке приложения.

i_am_kisly
17.04.2015, 01:25
Почему? Смотри, я получаю пакет, кидаю в приемную очередь. Из очереди его вытягивает парсер, собственно парсит и кидает ответ в очередь на отправку. Отправляющий поток достает подготовленный пакет из очереди "на отправку" и отправляет. Если отправка пакета инициирована клиентом, то да главный поток через эвенты. Меня больше мучает вопрос почему L2J то отвечает на авторизацию, то нет.

Yegor
17.04.2015, 03:23
Это вопрос к L2J. Попробуй в режиме отладки логин ядра сервера посмотреть почему он посылает лесом.

А данные из какого потока л2 реально что обрабатывает получены путем навешивания хуков на функции и вычисления threaid потока. При отправке threaid совпал с threaid главного потока окна.

Распакованные пакеты в очередь AddNetworkQue вызываются из другого потока, но весьма вероятно что их вытаскивание и разбор ведется все в том же главном потоке. С этим я думаю и связана эпическая тормознутость клиента л2, особенно при медленном скармливании ему большого объема серверных пакетов.