Чтение сокетного ответа в цикле - PullRequest
1 голос
/ 21 февраля 2010

у меня есть:

char buf[320];

read(soc, buf, sizeof(buf));
//print buf;

Однако иногда ответ намного больше, чем 320 символов, поэтому я пытаюсь запустить чтение в цикле, чтобы не занимать слишком много места в памяти. Я попытался прочитать (soc, buf, sizeof (buf)), но это снова печатает только те же первые x символов. Как бы я напечатал оставшиеся символы, которые не помещались в первые 320 символов в цикле?

Спасибо

Ответы [ 2 ]

2 голосов
/ 21 февраля 2010

Измените ваш цикл на что-то вроде:

while(1)
{
    int numread;

    if ((numread = read(soc, buf, sizeof(buf) - 1)) == -1)
    {
        perror("read");
        exit(1);
    }

    if (numread == 0)
       break;

    buf[numread] = '\0';

    printf("Reply: %s\n", buf);
}

по причинам, указанным Николой.

1 голос
/ 21 февраля 2010

Каждый раз, когда вы вызываете read( s, buf, buf_size ), ядро ​​копирует min( buf_size, bytes_available ) в buf, где bytes_available - число байтов, уже полученных и ожидающих в буфере приема сокета . Системный вызов read(2) возвращает количество байтов, помещенных в буфер приложения, или -1 в случае ошибки, или 0 для подачи сигнала EOF, то есть close(2) сокета на передающей стороне. Таким образом, при повторном использовании буфера только его часть может быть перезаписана новыми данными. Также обратите внимание, что -1 оценивается как true в C и C ++. Это, вероятно, тот случай, когда вы бьете.

printf(3) ожидает строка с нулевым символом в конце для спецификатора формата %s. Байты, считанные из сокета, могут не содержать байт '\0', что позволяет печатать printf(3) до тех пор, пока он не найдет ноль где-то ниже. Это может привести к переполнению буфера .

Точки здесь:

  1. Всегда проверяйте значение, возвращаемое с read(2)
  2. Если вы печатаете строки, считанные из сокета - всегда заканчивайте их нулем вручную.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...