Почему поведение select отличается при попытке чтения и записи сокетов?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Почему поведение select отличается при попытке чтения и записи сокетов?

Сообщение Anonymous »

Предположим, у нас есть дескриптор клиентского файла, принятый с помощью Accept()

Код: Выделить всё

client_socket = accept(_socket, (sockaddr *)&client_addr, &len)
Теперь мы устанавливаем этот файловый дескриптор в fd_set для чтения и записи:

Код: Выделить всё

fd_set readfds;
fd_set writefds;

//zero them
FD_ZERO(readfds);
FD_ZERO(writefds);

//set the client_socket
FD_SET(client_socket, &readfds);
FD_SET(client_socket, &writefds);
теперь мы используем select, чтобы проверить, доступен ли сокет для чтения или записи:

Код: Выделить всё

select(FD_SETSIZE, &readfs, &writefds, NULL, NULL)
Теперь мы проверяем, можем ли мы сначала прочитать все байты из него.

Код: Выделить всё

if (FD_ISSET(client_socket, &readfds) {
read(client_socket, &buf, 4096);
}
//assume that buf is big enough and that read returns less than 4096
В следующем цикле мы сбрасываем fd_sets, как и раньше.
Теперь select позволит нам записать наш ответ клиенту:

Код: Выделить всё

if (FD_ISSET(client_socket, &readfds) {
write(client_socket, &buf, len(buf));
}
До сих пор все работало нормально, но теперь происходит странное поведение.
Предположим, что наш клиент сказал нам поддерживать соединение,
в этом случае мы бы установили fd_set так же, как и раньше:

Код: Выделить всё

//zero them
FD_ZERO(readfds);
FD_ZERO(writefds);

//set the client_socket
FD_SET(client_socket, &readfds);
FD_SET(client_socket, &writefds);
// reading not allowed
При использовании select now мы сможем снова писать, но не сможем читать из client_socket.
НО, если мы изменим настройку writefds на ноль, это will позволит нам читать, хотя мы ничего не меняли в readfds.

Код: Выделить всё

//zero them
FD_ZERO(readfds);
FD_ZERO(writefds);

//set the client_socket
FD_SET(client_socket, &readfds);
//FD_SET(client_socket, &writefds); -> don't set the file-descriptors for write
// now reading is allowed
Может кто-нибудь объяснить мне, правильное ли это поведение select или это моя вина, возможно, в других частях кода, которые я не показывал (слишком сложно).
/>Мне кажется, что поведение select является случайным при установке обоих наборов (запись и чтение).
Я знаю, что есть способ обойти это, сохраняя своего рода состояние, чтобы решить, хотим ли мы установить чтение файловых дескрипторов или запись файловых дескрипторов, но я надеялся на более чистое решение.


Подробнее здесь: https://stackoverflow.com/questions/714 ... te-sockets
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»