2015-12-25 6 views
-1

Недавно я был возился с некоторыми сокетами, пытаясь сделать программу клиент/сервер. До сих пор я был успешным, но, похоже, я попал в блокпост. Для некоторых быстрых справочной информации, я сделал сервер, который может принять соединение, и когда все настроено и подключение к клиенту производится, этот блок кода начинает exectue:Очистка буфера чтения() при использовании сокета

while(1){ 
     read(newsockfd, &inbuffer, 256); 


     std::cout << "Message from client " << inet_ntoa(cli_addr.sin_addr) << " : "; 
     for(int i = 0; i < sizeof(inbuffer); i++){ 
      std::cout << inbuffer[i]; 

     } 
     std::cout << std::endl; 

} 

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

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

Спасибо за любую помощь.

+1

Не добавляйте метки для несвязанных языков. C не C++ не C – Olaf

+0

Я положил C, потому что некоторые из используемых библиотек являются средними для C – Sock314

ответ

1

Вы не проверяете возвращаемое значение read. Поэтому, если другой конец закрывает соединение или есть ошибка, вы просто наведете цикл навсегда, выводя все, что попадает в буфер. Вы, вероятно, захотите:

while(1){ 
    int msglen = read(newsockfd, &inbuffer, 256); 
    if (msglen <= 0) break; 

    std::cout << "Data from client " << inet_ntoa(cli_addr.sin_addr) << " : "; 
    for(int i = 0; i < msglen; i++){ 
     std::cout << inbuffer[i]; 
    } 
    std::cout << std::endl; 

} 

Обратите внимание, что я изменил слово «сообщение» на «данные». Вот почему:

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

Это неверное описание. В приведенном выше коде нет понятия «сообщение», а TCP не сохраняет границы сообщений приложения. Поэтому не только это неправильно, но и не может быть правильным, потому что слово «сообщение» не имеет никакого значения, которое могло бы применяться в этом контексте. TCP не «склеивает» байты, которые передаются в одном вызове функции отправки.

Смежные вопросы