Когда у вас есть неблокирующий ввод-вывод, и вы хотите сделать что-то, например, отправить данные, прочитать конкретный ответ от этой отправки, вам нужно настроить какое-то соответствующее состояние, чтобы, когда придет следующий набор данных, вы точно знали, что это принадлежит, и поэтому вы знаете, что с ним делать.
Я могу придумать несколько способов сделать это:
Создайте конечный автомат общего назначения, в котором вы отправляете данные и читаете данные, и всякий раз, когда вы читаете данные, вы можете сказать, в каком состоянии находится сокет и, следовательно, что вы должны делать с прочитанными данными.
Создайте временный набор прослушивателей, куда вы отправляете данные, затем добавьте временный прослушиватель (вы можете использовать .once()
) для входящих данных, специально предназначенный для их обработки так, как вы ожидаете от этого ответа. Когда данные поступают, убедитесь, что слушатель удален.
В вашем примере псевдокода недостаточно информации, чтобы кто-либо мог сделать более конкретное предложение. TCP по своей природе управляется потоком. У него нет встроенного смысла сообщения или пакета. Итак, то, что вы показываете, даже не показывает самый базовый уровень любого протокола TCP, который заключается в том, как узнать, когда вы получили полный ответ.
Даже ваш reply = s.recv()
, показанный на каком-то другом языке, нецелесообразен в TCP (независимо от языка), потому что s.recv()
нужно знать, когда он получил полное сообщение/фрагмент/что бы вы ни ожидали получить. TCP доставляет данные в том порядке, в котором они были отправлены, но не имеет никакого отношения к тому или иному пакету информации, который идет вместе. Вы должны предоставить это поверх уровня TCP. Общие методы, используемые для разграничения сообщений:
- Некоторый разделитель сообщения (например, возврат каретки или перевод строки, нулевой байт или какой-либо другой тег - все они, как известно, не встречаются внутри самого сообщения)
- Сначала отправляется длина, чтобы читатель точно знал, сколько байтов нужно прочитать.
- Оборачивать сообщения в какой-то контейнер, где начало и конец контейнера четко определены структурой контейнера (обратите внимание, что варианты 1 и 2 выше — это просто конкретные реализации такого контейнера). Например, протокол webSocket использует очень специфическую модель контейнера, которая включает некоторые данные о длине и другую информацию.
Я думал показать вам пример использования socket.once('data', ...)
для прослушивания определенного ответа, но даже это не будет работать должным образом, если вы не знаете, как очертить входящее сообщение, чтобы можно было узнать, когда вы получили полное входящее сообщение.
Таким образом, одним из ваших первых шагов будет реализация уровня поверх TCP, который считывает данные и знает, как разбить их на отдельные сообщения (знает, когда пришло полное сообщение, и как разбить несколько сообщений, которые могут поступать). а затем генерирует собственное событие в сокете, когда приходит целое сообщение. Тогда и только тогда вы сможете приступить к реализации остальной части вашего конечного автомата, используя описанные выше методы.
person
jfriend00
schedule
18.07.2019
socket
. Любое более подробное руководство должно знать точный протокол, который вы пытаетесь реализовать. - person jfriend00   schedule 19.07.2019