Название: GUI<<->Console обмен сообщениями и данными. Отправлено: MaxoBik от Август 03, 2015, 23:33 Доброго времени суток, есть консольное приложения не на QT и есть QT GUI приложения, которое запускает это консольное приложен. Так вот, между этими процессами нужно наладить обмен сообщениями и передачу из консольного приложения в GUI некоторой структуры данных - какую лучше всего схему IPC выбрать для этого?
Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Bepec от Август 04, 2015, 02:01 Socket'ы. Все иные способы или нуждаются в дополнительном контроле, или же труднореализуемы.
PS во всяком случае, лучше и кроссплатформеннее метода я не видел. Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Old от Август 04, 2015, 05:35 Доброго времени суток, есть консольное приложения не на QT и есть QT GUI приложения, которое запускает это консольное приложен. Так вот, между этими процессами нужно наладить обмен сообщениями и передачу из консольного приложения в GUI некоторой структуры данных - какую лучше всего схему IPC выбрать для этого? Пайпы (pipe).Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: __Heaven__ от Август 04, 2015, 09:24 Может быть ещё QProcess заинтересует. Общается с программой через потоки ввода/вывода.
Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Old от Август 04, 2015, 09:38 Может быть ещё QProcess заинтересует. Общается с программой через потоки ввода/вывода. Это и есть пайпы. :)Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: __Heaven__ от Август 04, 2015, 10:06 Упс. Извиняюсь за безграмотность :)
Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: __Heaven__ от Август 04, 2015, 10:08 Хочу развить тему и узнать, а что из себя представляют сокеты? Википедия особо не помогла разобраться.
Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Old от Август 04, 2015, 10:22 Хочу развить тему и узнать, а что из себя представляют сокеты? Википедия особо не помогла разобраться. Сетевые сокеты: QTcpSocket/QUdpSocket.Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: __Heaven__ от Август 04, 2015, 10:41 Ааа. То есть подразумевается, что на одной машине будет происходить общение через 127.0.0.1...
Голосую за QProcess! :) Кстати, я ещё наткнулся на метод разделения памяти. на сколько он хорош? Я так понял, что его преимущественно лучше использовать, если пишешь какой-то решатель, а в остальных случаях - QProcess. Или я ошибаюсь? Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Fregloin от Август 04, 2015, 11:15 есть еще QLocalSocket...
Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: MaxoBik от Август 04, 2015, 11:43 Может быть ещё QProcess заинтересует. Общается с программой через потоки ввода/вывода. Это и есть пайпы. :)есть еще QLocalSocket... Тот же PIPE в Windows. Да я читал какие есть способы в IPC в QT, мне вот нужно понять, что выбрать и как меньшими усилиями это реализовать.Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Old от Август 04, 2015, 12:13 QProcess, насколько я понял использует только в Windows Нет, пайпы это понятие кроссплатформенное. И появились они на юниксе.и только для записи в запускаемый процесс Организуются две трубы, т.е. связь двусторонняя.при таком раскладе как мне получить структуру данных из консольного приложения? Сериализировать/приводить ее в текст и выводить в stdout? Зачем ее приводить в текст. Пайп это канал данных, вы туда можете писать что захотите.Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: MaxoBik от Август 04, 2015, 13:07 Зачем ее приводить в текст. Пайп это канал данных, вы туда можете писать что захотите. Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Old от Август 04, 2015, 13:11 Ну а как еще? К примеру пайпы QProcess - я подключился к сигналу readyReadStandardOutput, в нем получаю readAllStandardOutput, но проблема в том как я буду определять что это строка или структура данных которую записали в stdout в консольном приложении через fwrite? Для любого обмена между несколькими участниками нужен протокол этого общения. Вы можете передавать команды/запросы от GUI к бекэнду, а он будет возвращать вам результаты, хоть строками, хоть бинарными структурами.Как вы придумаете протокол, согласно этого протокола и будете определять, что вам шлет бекэнд. Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: __Heaven__ от Август 04, 2015, 13:17 Вы же заранее знаете в каком порядке у вас будут поступать данные? Вот и подставляйте их в соответствующие ячейки структуры. Главное при чтении не забывайте длину проверять.
Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: MaxoBik от Август 04, 2015, 13:18 Ну а как еще? К примеру пайпы QProcess - я подключился к сигналу readyReadStandardOutput, в нем получаю readAllStandardOutput, но проблема в том как я буду определять что это строка или структура данных которую записали в stdout в консольном приложении через fwrite? Для любого обмена между несколькими участниками нужен протокол этого общения. Вы можете передавать команды/запросы от GUI к бекэнду, а он будет возвращать вам результаты, хоть строками, хоть бинарными структурами.Как вы придумаете протокол, согласно этого протокола и будете определять, что вам шлет бекэнд. Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: qate от Август 04, 2015, 13:19 ответ будет точнее, если будет известно что делает консольное приложение
Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Old от Август 04, 2015, 13:21 Ну, грубо говоря это и есть сериализация данных. Нет, серилизация это перевод данных из одного представления в другое.Протокол это правила взаимодействия нескольких участников. Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: MaxoBik от Август 04, 2015, 13:22 ответ будет точнее, если будет известно что делает консольное приложение Это вообще не важно что оно делает, здесь разговор про обмен данными между двумя процессами.Вы же заранее знаете в каком порядке у вас будут поступать данные? Вот и подставляйте их в соответствующие ячейки структуры. Главное при чтении не забывайте длину проверять. Через это же пайпы будет идти и строки, ладно я понял направления, попробую через пайпы и свою кастомную сериализацию.Всем СПАСИБО за подсказки. Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Bepec от Август 04, 2015, 16:22 Я б всё же советовал socket'ы. Там меньше подводных камней и очень быстро можно организовать сетевое взаимодействие :)
Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Old от Август 04, 2015, 20:08 Я б всё же советовал socket'ы. Там меньше подводных камней и очень быстро можно организовать сетевое взаимодействие :) А какие подводные камни в пайпах?Прямой канал данных, без дополнительного оверхеда, связанного с накручиванием/раскручиванием заголовков данных по всему сетевому стеку, который будет у сетевых сокетов. Я еще пойму локальные сокеты, но в венде их вроде нет (точно не знаю). Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: MaxoBik от Август 04, 2015, 22:00 В общем QProcess как PIPE в винде использовать нереально - нет возможности без кучи багов читать stdin в неблокирующем режиме, да у меня еще и в потоках это дело - вообще начинается дикие пляски. В nix все прекрасно работает через select, в виндовс дохлая затея. Придется QLocalSocket использовать.
Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Old от Август 04, 2015, 22:04 В общем QProcess как PIPE в винде использовать нереально - нет возможности без кучи багов читать stdin в неблокирующем режиме, да у меня еще и в потоках это дело - вообще начинается дикие пляски. В nix все прекрасно работает через select, в виндовс дохлая затея. Придется QLocalSocket использовать. Если вы используете QProcess, то у него есть сигнал, о приходе новых данных.Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: MaxoBik от Август 04, 2015, 22:11 Если вы используете QProcess, то у него есть сигнал, о приходе новых данных. Да нет, с QT приложениям то все нормально, с консольным приложениям написаным на чистом С\С++, которое и запускает мой QT GUI клиент, проблемы со stdin-ом в виндовс, придется создавать поток, который будет читать stdin, добавлять ему синхронизацию и прочие и прочие мелочи. Нет возможности в виндовс нормально читать из stdin продолжительное время в неблокирующем режиме.Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Old от Август 04, 2015, 22:15 Да нет, с QT приложениям то все нормально, с консольным приложениям написаным на чистом С\С++, которое и запускает мой QT GUI клиент, проблемы со stdin-ом в виндовс, придется создавать поток, который будет читать stdin, добавлять ему синхронизацию и прочие и прочие мелочи. Нет возможности в виндовс нормально читать из stdin продолжительное время в неблокирующем режиме. Такие возможности есть, boost.process прекрасно это умеет.Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: MaxoBik от Август 04, 2015, 22:31 Да нет, с QT приложениям то все нормально, с консольным приложениям написаным на чистом С\С++, которое и запускает мой QT GUI клиент, проблемы со stdin-ом в виндовс, придется создавать поток, который будет читать stdin, добавлять ему синхронизацию и прочие и прочие мелочи. Нет возможности в виндовс нормально читать из stdin продолжительное время в неблокирующем режиме. Такие возможности есть, boost.process прекрасно это умеет.Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Old от Август 04, 2015, 22:35 Ну да, а сверху еще помазать Boost Asio, но мне тянуть еще и Boost жирно будет как-то - все равно что забивать почтовые гвозди кувалдой, я попробую лучше стандартными методами QT и ОС реализовать. Ну так в boost.process и можно посмотреть как он это делает в венде.Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: MaxoBik от Август 04, 2015, 22:38 Ну да, а сверху еще помазать Boost Asio, но мне тянуть еще и Boost жирно будет как-то - все равно что забивать почтовые гвозди кувалдой, я попробую лучше стандартными методами QT и ОС реализовать. Ну так в boost.process и можно посмотреть как он это делает в венде.Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Bepec от Август 04, 2015, 22:52 А можно просто использовать сокеты :D
Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Old от Август 05, 2015, 07:10 А можно просто использовать сокеты :D Для обеспечения асинхронной работы с сокетами понадобятся такие-же телодвижения.Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Пантер от Август 05, 2015, 08:08 Для асинхронного чтения stdin нужно использовать QSocketNotifier. Выдернул из рабочего проекта:
Код
Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Old от Август 05, 2015, 08:12 Для асинхронного чтения stdin нужно использовать QSocketNotifier. Выдернул из рабочего проекта: У ТС консольная программа без Qt.QSocketNotifier умеет отслеживать дескрипторы под вендой? Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Пантер от Август 05, 2015, 08:24 Для асинхронного чтения stdin нужно использовать QSocketNotifier. Выдернул из рабочего проекта: У ТС консольная программа без Qt.QSocketNotifier умеет отслеживать дескрипторы под вендой? Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Old от Август 05, 2015, 08:32 Не проверял, но, насколько я знаю, да. А вот я сомневаюсь. :)В linux через QSocketNotifier можно пулить любые дескрипторы, там все файл. А вот в венде даже для последовательного порта, так сказать, свой API. :) Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Пантер от Август 05, 2015, 08:35 Не буду спорить, ибо виндов нету под рукой. В любом случае, можно написать свой вариант для обеих ОС. Не думаю, что это займет много времени. Но сокеты тоже хороший вариант, ибо в любой момент можно программы разнести на разные копмы и все будет работать.
Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: kuzulis от Август 05, 2015, 08:46 Цитата: Пантер Не проверял, но, насколько я знаю, да. Нет. QSocketNotifier можно использовать только для posix-дескрипторов. В винде это сработает только для сокетов (для которых использовались POSIX совместимые вызовы). В иных случаях для винды нужно использовать QWinEventNotifier и/или приватный QWinOverlappedIoNotifier, в зависимости от ситуации. Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: MaxoBik от Август 05, 2015, 11:58 Не проверял, но, насколько я знаю, да. Нет, не умеет - я уже это все давно проверил.QProcess в винде подменяет stdin,stdout,stderr на свои пайпы для приложения через стартовый данные процесса(STARTUPINFO), я хотел дернуть их оттуда, но как оказалось они анонимные и как следствия не асинхронные. А boost судя по всему передает туда named pipes со всеми вытекающими. Крч. сделать асинхронный stdin в виндовс не тривиальная задача, в 8-ке появляются еще отдельные особенности. Проще заменить stdin на named pipe в виндовс. Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: MaxoBik от Август 06, 2015, 13:50 Оказывается что в QT5 они сделали named pipes(\5.4\Src\qtbase\src\corelib\io\qprocess_win.cpp), но как-то криво сделали - нет ни OVERLAPPED ни WaitForMultipleObjects нету.
Непонятно как это еще можно использовать в самой программе клиенте. К примеру я получил и достал оттуда хендл именнованого пайпа stdin: Цитировать STARTUPINFO startInfo; HANDLE hStdInput; .... GetStartupInfoW(&startInfo); if( ( STARTF_USESTDHANDLES & startInfo.dwFlags ) == STARTF_USESTDHANDLES && ( hStdInput=startInfo.hStdInput ) != INVALID_HANDLE_VALUE ){ /// как его читать асинхронно здесь? } Но как его читать здесь без структуры OVERLAPPED? Ведь если не указать ее для ReadFile будет идти синхронное чтения. Для Asynchronous I/O нужно ее указывать, но где ее взять? Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Bepec от Август 06, 2015, 13:59 Поэтому переделайте всё на сокеты и будет вам счастье на всех платформах и без подводных камней :D
PS причем переделывать то ничего особо и не надо, дернуть из примера пару функций и всё :) Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: hydra13 от Август 20, 2015, 16:00 QSharedMemory
Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: Bepec от Август 20, 2015, 16:09 Есть только 2 способа нормально передавать данные - сокеты и пайпы. Пайпы в винде суровы, им обвязку писать и писать. А сокеты везде одинаковы.
Название: Re: GUI<<->Console обмен сообщениями и данными. Отправлено: MaxoBik от Август 21, 2015, 22:09 QSharedMemory Придется плясать с семафорами, да и не нужно это - мои данные почти полностью состоят из текста, которые нужно просто показать пользователя. Крч. я все сделал через пайпы с упаковкой данных в JSON. Именованые пайпы кстати в QT для Windows просто для вида, половина кода не реализована, пришлось писать с нуля. |