Вы используете select()
, чтобы проверить, является ли данный сокет находится в читаемом состояния перед вызовом connect()
на тот же сокет. Это никогда не сработает. Несвязанный TCP-сокет никогда не будет в читаемом состоянии и не может использоваться с select()
до тех пор, пока в нем не будет вызван connect()
.
Единственный способ реализации тайм-аут для connect()
вызова поместить гнездо в неблокирующем режиме первого (сокеты блокировки по умолчанию), а затем вызвать connect()
(который возвращает EINPROGRESS
ошибку, если сокет пытается подключиться), а затем используйте select()
, чтобы дождаться, когда сокет введет состояние , доступное для записи, с сообщением об успешном завершении соединения или с ошибкой , указывающей, что соединение не выполнено.
Попробуйте это:
fcntl(s, F_SETFL, O_NONBLOCK);
Или:
flags = 1;
ioctl(s, FIOBIO, &flags);
В зависимости от используемой платформы.
Тогда:
check_control = connect(s, (struct sockaddr*) &indirizzo_remoto, sizeof(indirizzo_remoto));
if (check_control == -1)
{
if (errno != EINPROGRESS)
{
printf("Errore connect()\n");
exit(-1);
}
FD_ZERO(&wset);
FD_SET(s, &wset);
FD_ZERO(&eset);
FD_SET(s, &eset);
tval.tv_sec = TIMEOUT;
tval.tv_usec = 0;
n = select(s+1, NULL, &wset, &eset, &tval);
if (n == -1)
{
printf(" select() failed \n");
exit(-1);
}
if (n == 0)
{
printf("Timeout. I'll shutdown the client");
exit(-1);
}
if (FD_ISSET(s, &eset))
{
printf("Cannot connect. I'll shutdown the client");
exit(-1);
}
int err = -1;
getsockopt(s, SOL_SOCKET, SO_ERROR, &err, sizeof(err));
if (err != 0)
{
printf("Cannot connect. I'll shutdown the client");
exit(-1);
}
}
// connected...
Да, с телнет это работает! – user2467899
Это неправильно? Поскольку я хочу, чтобы это был сервер, когда клиент пытается подключиться к нему, если он занимает 30 секунд, клиент остановится и закроет сокет – user2467899
(извините за английский) ....: Я хочу, чтобы если сервер/когда клиент попытается подключиться к нему – user2467899