Я не верю, что этот код действительно вызывается только один раз в «неблокирующей» версии (кавычки, потому что он еще не является неблокирующим, как указал Мистер, посмотрите здесь ), проверьте еще раз , Если блокирующая и неблокирующая версии согласованы, неблокирующая версия должна вернуть total_sent (или размер). С return 0
вместо звонящего, скорее всего, поверит, что ничего не было отправлено. Что вызвало бы бесконечную отправку ... разве это не то, что происходит?
Также ваш «неблокирующий» код довольно странный. Кажется, вы используете select, чтобы блокировать его в любом случае ... Хорошо, с таймаутом в 1 с, но почему бы вам не сделать его действительно не блокирующим? то есть: удалите все данные select
и проверьте на наличие ошибки в write()
с ошибкой EWOULDBLOCK
. select
или poll
для мультиплексирования.
Также вы должны проверить ошибки для select и использовать FD_ISSET, чтобы проверить, действительно ли сокет готов. Что если тайм-аут на 1 с действительно произойдет? Или если выбор остановлен каким-то прерыванием? И если при записи происходит ошибка, вы должны также написать, какая ошибка, это гораздо более полезно, чем ваше общее сообщение. Но я думаю, что эта часть кода еще далека от завершения.
Насколько я понимаю, ваш код, вероятно, должен выглядеть примерно так (если код выполняется в уникальном потоке или в потоке, или разветвление при принятии соединения изменит детали):
// Creation of socket in class constructor
sock = ::socket(PF_INET, socket_type, 0);
fcntl(sock, F_SETFL, O_NONBLOCK);
// And then when accept is called on the socket
result = ::accept(sock, NULL, NULL);
if (result > 0) {
// A connection was made with a client
client = result;
fcntl(client, F_SETFL, O_NONBLOCK);
}
// Nonblocking socket code
result = ::write(client, &message[total_sent], (size - total_sent));
if (result == -1) {
if (errno == EWOULDBLOCK){
return 0;
}
std::cerr << "An error has occured while writing to the server."
<< std::endl;
return result;
}
return size;