Как обмениваться двоичными данными между процессами в 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 - это еще одна подходящая, но полностью не читаемая кодировка.


есть много..

Я бы прочитал Стивенса.

http://www.kohala.com/start/unpv22e/unpv22e.html


обычно используется fread и fwrite для обмена двоичными структурами между процессами. Он отлично работает для записей фиксированной длины,и нет проблем с отправкой нулей и т. д.

за свою долгую карьеру я обнаружил, что в большинстве приложений намного лучше обмениваться строками ascii, легко разбираемыми (например,scanf), вместо двоичных данных. Таким образом, сообщения могут наблюдаться и регистрироваться, а отдельные процессы могут быть протестированы с помощью telnetting и typing (обычно наклеивание) на них. Это просто упрощает разработку, если программист может просто читать трафик сообщений.


надежный обмен данными? Это заставляет меня думать о библиотеке 0MQ (ZeroMQ):http://zeromq.org

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

Добро пожаловать в облако.