Проверьте, доступен ли дескриптор файла сокета? - PullRequest
3 голосов
/ 21 мая 2009

Если я получил файловый дескриптор (сокет fd), как проверить, доступен ли этот fd для чтения / записи? В моей ситуации клиент подключился к серверу и мы знаем fd. Однако сервер отключит сокет, есть ли какие-нибудь подсказки, чтобы проверить это?

Ответы [ 5 ]

4 голосов
/ 21 мая 2009

Вы хотите, чтобы fcntl() проверил настройки чтения / записи на fd:

#include <unistd.h>
#include <fcntl.h>

int    r;

r = fcntl(fd, F_GETFL);
if (r == -1)
        /* Error */
if (r & O_RDONLY)
    /* Read Only */
else if (r & O_WRONLY)
    /* Write Only */
else if (r & O_RDWR)
    /* Read/Write */

Но это отдельная проблема, когда сокет больше не подключен. Если вы уже используете select() или poll(), то вы почти на месте. poll() вернет статус, если вы укажете POLLERR в events и проверите его в revents.

Если вы делаете нормальный блокирующий ввод / вывод, то просто обрабатывайте ошибки чтения / записи по мере их появления и корректно восстанавливайте.

0 голосов
/ 26 мая 2009

Я нашел, что recv может проверить. когда сокет fd плохой, устанавливается некоторое errno.

ret = recv(socket_fd, buffer, bufferSize, MSG_PEEK); 
if(EPIPE == errno){
// something wrong
}
0 голосов
/ 21 мая 2009

В C # на этот вопрос дан ответ здесь

Как правило, разъединение через сокет является асинхронным и требует определенного опроса. Асинхронное чтение в сокете обычно возвращается, если оно также закрыто, что дает вам возможность быстрее узнать об изменении статуса. Winsock (Windows) имеет возможность зарегистрироваться для получения уведомлений о разъединении (но опять же, это может не произойти в течение длительного времени после того, как другая сторона «уходит», если вы не используете какой-либо тип «keepalive» (SO_KEEPALIVE, который путем по умолчанию может не отображаться часами или пульса на уровне приложения).

0 голосов
/ 21 мая 2009

Ну, вы можете позвонить select (). Если сервер отключился, я полагаю, что в конечном итоге вы получите код ошибки ... Если нет, вы можете использовать select (), чтобы определить, готов ли ваш сетевой стек отправлять больше данных (или получать их).

0 голосов
/ 21 мая 2009

Для этого вы можете использовать select() или poll().

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