Проверьте, подключен ли сокет или нет.
У меня есть приложение, которое должно отправить некоторые данные на сервер в какое-то время. Простым способом было бы закрыть соединение, а затем снова открыть его, когда я хочу что-то отправить. Но я хочу сохранить соединение открытым, поэтому, когда я хочу отправить данные, я сначала проверяю соединение, используя эту функцию:
bool is_connected(int sock)
{
unsigned char buf;
int err = recv(sock,&buf,1,MSG_PEEK);
return err == -1 ? false : true;
}
Плохая часть заключается в том, что это не работает. Он зависает, когда нет данных для получения. Что я могу сделать? Как я могу проверить, все ли соединение открыто?
Ответы
Ответ 1
Не проверять сначала, а затем отправлять. Он потратил впустую усилия и не будет работать в любом случае - статус может измениться между тем, когда вы проверяете и когда вы отправляете. Просто делайте то, что хотите, и обрабатывайте ошибку, если она не работает.
Чтобы проверить статус, используйте:
int error_code;
int error_code_size = sizeof(error_code);
getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, &error_code, &error_code_size);
Ответ 2
Вам нужно включить неблокирующее поведение, установив O_NONBLOCK
с помощью fcntl
. Одним простым, но нестандартным способом делать неблокирующее чтение было бы использовать:
recv(sock, &buf, 1, MSG_PEEK | MSG_DONTWAIT);
После этого вы должны проверить errno, если он терпит неудачу. Он может выйти из строя с помощью EAGAIN
или может завершиться с ошибкой EBADF
или ENOTCONN
и т.д.
Очевидно, что самым простым и чистым способом борьбы с этим было бы избежать "забывания", если сокет подключен или нет. Вы заметите, что сокет будет отключен после того, как a recv
вернет 0 или send
вернет EPIPE
.
Ответ 3
Использование по умолчанию TCP не позволяет очень своевременно обнаруживать мертвые сокеты (вне нормального закрытия), поэтому я предлагаю, чтобы функция "is_connected", подобная этой, в значительной степени бесполезна для всех практических целей. Подумайте о том, как реализовать накладной уровень и отслеживать его, если он жив, на основе своевременных ответов (или их отсутствия).
edit: после публикации я вижу ссылку BoBTFish, которая фактически является тем же самым.