unistd.h read() считывает больше данных, чем записывается

StackOverflow https://stackoverflow.com/questions/873214

Вопрос

Я читаю/записываю данные из именованного канала.Что касается записи, то написано, что он записывает постоянные 110 байт.Что касается чтения, то большую часть времени он говорит, что читает 110 байт, и это правильно, но иногда он говорит, что читает 220 байт или 330 байт.Это верно в том смысле, что когда я его распечатываю, одно и то же сообщение выводится два или три раза подряд в рамках одного и того же чтения().В приведенном ниже коде для чтения я делаю что-то не так с memset, чтобы очистить символ?Я не могу придумать другого способа, которым он читает больше, чем записывается, если только в буфере что-то не осталось.

int fd1, numread;
char bufpipe[5000];

    while(1)
    {
        fd1 = open("/tmp/testPipe", O_RDONLY);
        numread = read(fd1,bufpipe, 5000);//->this should always be 110
        if(numread > 1)
        {
            printf("READ: %i", numread); 
            bufpipe[numread+1] = '\0';
            memset(bufpipe,'\0',5001);
            close(fd1);
        }
    }
Это было полезно?

Решение

Этот:

memset(bufpipe,'\0',5001);

перезаписывается на один байт, потому что у вас всего 5000 байт.

Но главная «проблема» в том, что read(..., 5000) всегда будет читать столько, сколько сможет, до 5000 байт - вы, похоже, предполагаете, что он будет читать только столько, сколько было записано за один раз автором, что не соответствует действительности.Если писатель записывает два пакета по 110 байт между двумя чтениями, то совершенно правильно, что читатель читает 220 байт.

Если вам нужно читать только один пакет за раз, вам придется сделать пакеты самоописывающими.Так, например, первые четыре байта содержат количество последующих байтов.Затем вы можете прочитать один пакет, прочитав четыре байта, преобразовав его в целое число, а затем прочитав это количество байтов данных.

Другие советы

Ваше предположение, что read будет выполнено сразу после write не правда.Процесс записи может выполнить запись в канал пару раз, прежде чем произойдет чтение.Записанные данные будут добавлены в конец буфера.Другими словами, чтение и запись не ориентированы на пакеты.Они ориентированы на поток.Это означает, что write просто добавляет данные в буфер и read просто получает все, что ему доступно.

Как вы синхронизируетесь с автором?Вам нужно просто прочитать то, что вы ожидаете (для чтения укажите 110())

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top