2015-03-30 7 views
0

Я пишу игрушку MUD клиент, который использует сокет TCP/IP для подключения к серверу telnet.Как узнать, что пакет данных полностью принят в telnet?

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

Теперь проблема возникает, когда ответ длинный и принят в 2 или более пакетах TCP/IP, поэтому регулярные выражения не совпадают, когда я запускаю их в ответах, поскольку они еще не завершены (первый или второй часть не совместима в одиночку).

Итак, вопрос в том, как узнать, что сервер завершает отправку пакета данных, прежде чем запускать на них регулярные выражения.

ответ

2

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

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

Если есть команда, которую вы можете отправить, которая не имеет эффекта геймплея, но имеет постоянный ответ с сервера (например, пинг), вы можете использовать его как сортировщик.

+0

вопрос: «Что такое разделитель?» и что вы подразумеваете под «игрой (почти) исключительно клиентом (а не самой telnet)»? –

+0

разделитель - это то, что вы хотите, прямо сейчас, ограничивая мои предложения запятыми и мои слова с помощью любой буквы, вам просто нужно найти или определить разделитель, который последовательно отделяет ваши сообщения друг от друга. Если игрок подключится через telnet, а не к вашему клиенту, и, например, ваш разделитель равен %%%, они будут видеть эти %%%, и вы можете этого не захотеть. – gia

+0

небольшое недоразумение здесь: серверная сторона не находится под моим контролем, я просто пишу общий клиент грязи. поэтому я не могу заставить сервер добавлять разделители в конец данных. –

2

Короткий ответ: вы не

TCP/IP является последовательный протокол, что не имеет ни малейшего представления о пакетов.

Если протокол прикладного уровня использует пакеты (большинство из них), то у вас есть два варианта:

  • использует транспортный уровень, который поддерживает пакеты изначально (UDP, SCTP, ...)

  • добавить пакетирования информацию в свой поток данных

Самый простой способ добавить пакетирования информации, является добавление разделителем символов (обычно \n); очевидно, вы не можете использовать разделитель в полезной нагрузке, тогда как уже зарезервировано для других целей.

Если вам нужно, чтобы иметь возможность передавать любой символ в полезной нагрузке (так что вы не можете заказать разделитель), использовать что-то вроде SLIP поверх TCP/IP

+0

Я знаю, что «не имеет понятия о пакетах». нужно каким-то образом определить, не будет ли больше данных, пока я не отправлю следующую команду. Иногда данные заканчиваются на «\ n», а иногда заканчивается каким-то другим символом, поэтому сервер явно не заботится о разделителе. –

+0

Теперь я предположим, что вы не пишете сервер и не можете его изменить. В этом случае вам придется разобраться в каждом конкретном случае. – gia

+0

да, так что это лучший способ сделать это, поскольку сервер может быть разные в любом случае. Я думал о том, чтобы ждать, как 200 мс, прежде чем действовать на данные ... –

2

Вы можете быть более подумав. Почти все глинистые разграничивают линии с LF, то есть \n (некоторые нечетные серверы будут использовать CRLF, \r\n или даже \n\r). Таким образом буферизуйте свой вход и сканируйте разделитель \n. Когда вы найдете его, переместите строку из входного буфера и запустите регулярные выражения.

Специальный случай - это команда telnet IAC GA, которую некоторые грязи используют для обозначения подсказок. Прочтите Telnet RFC для получения более подробной информации, https://tools.ietf.org/html/rfc854 и сделайте некоторое исследование проблем, связанных с грязью, например http://cryosphere.net/mud-protocol.html.

Практически говоря, с грязью вы никогда не столкнетесь с ожиданием длинной линии. Если между грязью и клиентом много отставания, вы не можете многое сделать с этим.

+0

проблема с этим решением будет заключаться в том, что каждая строка заканчивается подачей строки, например, вы отправляете «карту» и получаете карту ASCII вашего окружения. И я видел подсказки, которые заканчиваются «>», и больше ничего. –

+0

Неструктурированные данные (например, «карта», команда «help») являются проблемой для грязей вообще, и вы не собираетесь ее решать на уровне проблемы, о которой вы просите, если у вас нет контроля над сервером и клиент. Запросы, заканчивающиеся на '>', могут иметь после себя 'LF' или' IAC GA'. Вы сканируете IAC, не так ли? – georgek

+0

Я сканирую IAC, к сожалению, грязи играют по их собственным правилам. Сейчас я использую aardwolf в качестве образца грязи, и он заканчивает приглашение «нет» больше. Я могу изменить формат приглашения с помощью некоторых команд в грязи, но, как правило, это не хорошая идея для универсального клиента грязи полагаться на предопределенный формат. и у хорошо зарекомендовавших себя клиентов, которые я использую, нет проблем с обнаружением каких-либо подсказок без суеты. –