Чтение сообщения из сокета в C - PullRequest
6 голосов
/ 14 марта 2011

Я пытаюсь понять чтение из сокета в C (Linux), это только часть кода:

while(success == 0) {

    while((n = read(sockfd, buffer, BUFFSIZE, 0)) > 0) {
        printf("%s",buffer);
        bzero(buffer,BUFFSIZE);
    }
    success = 1;
    printf("###");

}

Сообщение печатается, но три хеша (###) никогда не печатаются?Зачем?Программа, кажется, блокирует чтение ().Здесь я делаю только печать, но мне нужно сделать буфер всего сообщения и затем обработать его.

Ответы [ 6 ]

7 голосов
/ 15 марта 2011

Программа на другом конце сокета не закрывает ее и не закрывает свои записи (которые являются вашими чтениями), поэтому ваш конец не знает, что все закончено - действительно, логически оно не закончено, пока другой конец не скажет, что вам больше нечего читать.

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

(Неблокирующий ввод-вывод - это нечто совершенно другое - он позволяет вам делать другие вещи, эффективно считывая данные из сокетов в одном потоке, но это не решает проблему определения того, когда вы закончили чтение из сокет, который является вашей проблемой.)

5 голосов
/ 15 марта 2011

Вы должны знать, насколько большим является полученное вами сообщение, и продолжать читать, пока не получите полное сообщение (чтение может вернуть только часть вашего сообщения).

do {
    nread = read(s, buf, to_read);
    if (nread < 0 && errno == EINTR)
            continue;
    if (nread < 0) {
            perror("read");
            exit(1);
    }

    if (nread == 0) {
            printf("socket closed");
            ... do something appropiate ...
            ... (reconnecting/exiting the loop with an error/...) ...
    }

    to_read -= nread;
    buf += nread;
} while (to_read > 0); 

to_read - длина в байтах, которую вы ожидаете прочитать. buf имеет достаточно места для этого. После каждого чтения обновляйте to_read и buf соответственно. И, конечно же, вы должны правильно исправлять ошибки.

1 голос
/ 15 марта 2011

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

ief2

0 голосов
/ 15 марта 2011

Ваш цикл while закончится, только когда n будет иметь значение ноль.

Когда вы ожидаете, что read вернет нулевое значение? Соответствуют ли данные, которые вы отправляете в этот сокет, условию, которое приведет к чтению, возвращающему ноль?

0 голосов
/ 15 марта 2011

Полагаю, ваш цикл while никогда не завершается, потому что чтение либо завершается успешно, либо блокируется.

0 голосов
/ 14 марта 2011

Попробуйте добавить \n. Иногда неоконченные строки не печатаются.

РЕДАКТИРОВАТЬ: Ой, подождите, вы имеете в виду программу не заканчивается?

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