Как обмениваться двоичными данными между процессами в Linux
Мне нужно создать приложение linux, которое будет выполнять сканирование беспроводной сети, поместить результат в структуру и отправить его как-то другому, основному приложению, которое будет использовать данные. Моя первоначальная идея состояла в том, чтобы создать канал в главном приложении, fork и запустить другой процесс execl, который может писать в канал. Что-то вроде этого:--2-->
pid_t pid = NULL;
int pipefd[2];
FILE* output;
char line[256];
pipe(pipefd);
pid = fork();
if (pid == 0)
{
// Child
close(pipefd[0]);
dup2(pipefd[1], STDOUT_FILENO);
dup2(pipefd[1], STDERR_FILENO);
execl("/sbin/wifiscan", "/sbin/wifiscan", (char*) NULL);
}
//Only parent gets here. Listen to what the wifi scan says
close(pipefd[1]);
output = fdopen(pipefd[0], "r");
while(fgets(line, sizeof(line), output))
{
//Here we can listen to what wifiscan sends to its standard output
}
это, однако, не будет работать с двоичными данными, если двоичный 0 появляется в выходных данных. Поэтому я мог бы либо отформатировать вывод приложение wifiscan для текста, отправьте его в pipe и проанализируйте в главном приложении или сделайте это умнее, чего я еще не знаю.
каковы другие способы надежного обмена данными между процессами в Linux?
4 ответов
я подозреваю, что происходит это fgets()
читает символы NUL правильно, но вы интерпретируете первый как конец строки, которая была прочитана. Это сложно, потому что fgets()
предназначен для текстового ввода, и он использует "\0 " в качестве часового, не возвращая количество прочитанных символов. Даже если вы знаете, что каждая строка будет \n
завершено, есть вероятность, что необработанные двоичные данные, встроенные в строку, будут включать \n
тоже. Итак, переключитесь на fread()
, который предназначен для двоичного кода. Вы можете поместить размер сообщения фиксированной длины (например, 2-байтовый, 4-байтовый) в передней части каждого сообщения, чтобы другая сторона могла прочитать это сначала, а затем сделать fread()
для точного размера сообщения, избегая грязных проблем с частичным сообщением читает.
если вы действительно хотите сохранить какой-то странный гибрид текста и двоичного кода, Вы можете попробовать использовать ftell()
после fgets()
чтобы узнать, насколько дальше по потоку вы находитесь, и, следовательно, сколько символов должно будь в своем буфере, но я никогда не видел, чтобы серьезная система делала что-то настолько хакерское.
для записи, не делая что-то заметно неэффективное, как шестнадцатеричное кодирование каждого символа в двоичных данных, вы можете просто кодировать хлопотный символ(ы). Например, можно использовать escape-последовательности строкового литерала C с представляя нуль и
\
один \
. Хотя менее легко визуально проверить, может быть проще программно кодировать / декодировать непечатаемые символы, использующие say octal \NNN
. Если есть много непечатаемых символов, то подход base-64 uuencode - например, используемый в вложениях электронной почты MIME - это еще одна подходящая, но полностью не читаемая кодировка.
обычно используется fread
и fwrite
для обмена двоичными структурами между процессами. Он отлично работает для записей фиксированной длины,и нет проблем с отправкой нулей и т. д.
за свою долгую карьеру я обнаружил, что в большинстве приложений намного лучше обмениваться строками ascii, легко разбираемыми (например,scanf
), вместо двоичных данных. Таким образом, сообщения могут наблюдаться и регистрироваться, а отдельные процессы могут быть протестированы с помощью telnetting и typing (обычно наклеивание) на них. Это просто упрощает разработку, если программист может просто читать трафик сообщений.
надежный обмен данными? Это заставляет меня думать о библиотеке 0MQ (ZeroMQ):http://zeromq.org
посмотрите, и в качестве бонуса ваши процессы смогут разговаривать даже на удаленных компьютерах.
Добро пожаловать в облако.