同じソケットを呼び出す前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...