Отправка структурированных данных по именованному каналу (Linux) - PullRequest
2 голосов
/ 11 августа 2010

Я использую именованный канал для IPC в системе Debian.Я буду отправлять некоторые данные в виде набора строк из сценария bash в фоновый запущенный процесс, написанный на коде C.

Данные, которые я хочу отправить, состоят из четырех строк, например, accountid, firstname, фамилия, описание.В настоящее время я отправляю данные в виде массива char, разделенного пробелами из моего скрипта bash.

echo "accountid firstname surname description" >$pipe

В фоновом процессе я читаю данные канала, как это, в массив char 'datain'

res = read(pipe_fd, datain, BUFFER_SIZE);

тогда я просто перебираю массив в поисках пробелов

например

char* p = datain;

char accountid[80];
char firstname[80];

// extract the accountid
while(p!='')
{
    accountid = p;
    ++p;
}

++p;

while(p!='')
{
    firstname = p;
    ++p;
}

и т. Д.

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

Спасибо

Ответы [ 2 ]

2 голосов
/ 11 августа 2010
  • Канал (именованный или нет) - это поток байтов.Если вы использовали один и тот же язык с обеих сторон, возможно, существует лучший способ отправки структурированных данных.В вашей ситуации ручное кодирование и декодирование, как и вы, на сегодняшний день является самым простым решением.

  • Не используйте пробелы для разделения полей, которые могут содержать пробелы, такие какимена людей.Используйте :, например /etc/passwd.

  • В C read сложно использовать, потому что вы должны заранее выбрать размер буфера и Вы должны вызывать его в цикле, потому что он может вернуть меньше размера буфера по прихоти.Функции из stdio.h (которые работают с FILE*, а не с дескриптором файла) проще в использовании, но все же требуют работы для обработки длинных строк.Если вас не волнует переносимость вне Linux, используйте getline:

    FILE *pipe = fdopen(fd, "r");
    char *line = NULL;
    size_t line_length;
    getline(&line, &line_length, pipe);
    

Затем используйте strchr, чтобы найти : s в строке.(Не пытайтесь использовать strtok, он подходит только для полей, разделенных пробелами, которые не могут быть пустыми.)

1 голос
/ 11 августа 2010

Начиная с 2010 года, вы можете закодировать свои данные в JSON или XML, которые легко доступны в виде библиотек для C и почти любого другого языка.

...