Если вы попытаетесь получить один байт, вы можете получить несколько ошибок, если у вас будет неблокирующий сокет и попытаться получить действительное соединение, вы получите ошибку WSAEWOULDBLOCK.
Зная это, мы можем проверить неблокирующую розетку вот так
bool connected(SOCKET sock)
{
char buf;
int err = recv(sock, &buf, 1, MSG_PEEK);
if(err == SOCKET_ERROR)
{
if(WSAGetLastError() != WSAEWOULDBLOCK)
{return false;}
}
return true;
}
Как вы можете видеть из возвращаемого значения recv recv может вернуть тайм-аут или несколько других ошибок для разъединения, я верю, что WSAEWOULDBLOCK - это единственное значение, которое он может вернуть, если была ошибка, но все еще подключена но вы можете дважды проверить этот список возвращаемых значений. Кроме того, флаг, используемый в recv (MSG_PEEK), означает, что данные по-прежнему доступны для чтения, когда вы посмотрите позже после проверки, поэтому вам не нужно беспокоиться о потере одного байта данных.
Я полагаю, что это будет хорошо работать только с неблокирующими сокетами, поскольку может блокироваться до получения данных. Если вы хотите использовать блокирующий сокет, вы можете установить его без блокировки с помощью ioctlsocket перед этой проверкой, а затем вернуть его на прежнее состояние.