Чтение / запись не работает в моем коде TCP - PullRequest
1 голос
/ 25 января 2012

У меня есть базовая программа клиент / сервер TCP.

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

void printout(int newsockfd, char buffer) {
n = write(newsockfd, a2, 256);
n = write(newsockfd, a3, 256);
n = write(newsockfd, a4, 256);
n = write(newsockfd, a5, 256);
n = write(newsockfd, a6, 256);
}

на сервере

void printout(char buffer[], int sockfd) {
bzero(buffer, 256);
n = read(sockfd, buffer, 256);
printf("%s\n", buffer);
n = read(sockfd, buffer, 256);
printf("%s\n", buffer);
n = read(sockfd, buffer, 256);
printf("%s\n", buffer);
n = read(sockfd, buffer, 256);
printf("%s\n", buffer);
n = read(sockfd, buffer, 256);
printf("%s\n", buffer);
}

a2, a3, a4, a5 и a6 являются строками. При первом запуске он печатает все правильно. Во второй раз он ничего не печатает, просто куча пустых строк. Когда я проверил, чтобы выяснить, что это за буфер, я понял, что это "". Вы знаете, в чем проблема или как я могу это исправить?

Ответы [ 2 ]

3 голосов
/ 25 января 2012

Трудно точно определить проблему, поскольку вы не показываете нам цикл.

Однако, одна вещь, которая выпадает, это то, что вы, кажется, ожидаете, что каждый вызов write() будет соответствоватьзвонок на read().Это не так, как работает TCP: пакеты получают фрагменты, вы можете получить частичное чтение и т. Д. Другими словами, TCP - это поток протокол , а не ориентированный на сообщения one.

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

Кроме того, поскольку вы обрабатываете 256-байтовые чанки как строки C, было бы разумно, чтобы сервер добавил свой собственный терминатор NULвместо того, чтобы полагаться на клиента, чтобы поставить один.

0 голосов
/ 25 января 2012

Ставлю, что вызов вашего сервера на bind() не удался при втором запуске. И так клиент звонит на connect(). Есть обработка ошибок для тех?

EDIT

Особенно при работе с простыми примерами TCP вполне обычно, когда первый запуск вашего сервера «удерживает» порт некоторое время после того, как сервер умирает. Когда вы запускаете сервер во второй раз, bind() завершится неудачей, и ваш серверный процесс не сможет listen() или accept() новых соединений. Объяснение деталей - тема другого вопроса.

Поскольку вашего сервера на самом деле нет, connect() не удастся выполнить на вашем клиенте, оставив вас с неподключенным сокетом. И все последующие чтения из этого сокета немедленно завершатся неудачей, оставив buffer, содержащий все 0. Это было бы возможным объяснением поведения, которое вы видите.

Можете ли вы исключить это объяснение? Вы проверяете, что bind() и connect() всегда возвращают 0?

...