関数connectのタイムアウト値を設定したいのですが、次のエラーが表示されます:「操作は現在進行中です」
私のコード:
if ((he = gethostbyname(authdefhost)) == NULL) {
snprintf(errbuf, CERRBUFSIZ - 1, "cannot resolve %s: %s\n", authdefhost, hstrerror(h_errno));
return -1;
}
sin.sin_family = AF_INET;
memcpy(&sin.sin_addr, he->h_addr_list[0], sizeof(struct in_addr));
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
snprintf(errbuf, CERRBUFSIZ - 1, "cannot create client socket: %s\n", strerror(errno));
return -1;
}
if ((fcntl(sd, F_SETFL, O_NONBLOCK) < 0))
printf("error on setting socket flags.");
if (connect(sd, (void *) & sin, sizeof(sin)) == -1) {
snprintf(errbuf, CERRBUFSIZ - 1, "cannot connect to server %s: %s\n", authdefhost, strerror(errno));
close(sd);
return -1;
}
FD_ZERO(&fdset);
FD_SET(sd, &fdset);
int rv;
if ((rv = select(sd + 1, NULL, &fdset, NULL, &tv)) == -1) {
printf("error occurred on select function.");
return -1;
}
else if (rv == 0) {
printf("time out occurred.");
return -1;
}
else {
printf("connection established");
return sd;
}
非ブロッキングソケットでconnect()
を呼び出すと、接続ハンドシェイクの完了をブロックする代わりにEINPROGRESS
を取得します。次に、書き込み可能性についてselect()
を実行し、ソケットエラーをチェックして、接続が完了したかどうかを確認する必要があります。
Linuxから connect()
manpage :
EINPROGRESS ソケットはノンブロッキングであり、接続をすぐに完了できません 。 書き込み用のソケットを選択することにより、完了のために(2)またはpoll(2)を選択することができます。 select(2)が 書き込み可能性を示したら、getsockopt(2)を使用してレベル SOL_SOCKETでSO_ERRORオプションを読み取り、connect()が正常に完了したかどうかを判断します (SO_ERRORはゼロ)または失敗しました(SO_ERRORは、ここにリストされている通常の エラーコードの1つであり、失敗の理由を説明しています)。