web-dev-qa-db-ja.com

connect(function)エラーで操作中エラー

関数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;
}
15
iyasar

非ブロッキングソケットでconnect()を呼び出すと、接続ハンドシェイクの完了をブロックする代わりにEINPROGRESSを取得します。次に、書き込み可能性についてselect()を実行し、ソケットエラーをチェックして、接続が完了したかどうかを確認する必要があります。

Linuxから connect() manpage

EINPROGRESS 
 
ソケットはノンブロッキングであり、接続をすぐに完了できません
。 
書き込み用のソケットを選択することにより、完了のために(2)またはpoll(2)を選択することができます。 select(2)が
書き込み可能性を示したら、getsockopt(2)を使用してレベル
 SOL_SOCKETでSO_ERRORオプションを読み取り、connect()が正常に完了したかどうかを判断します
(SO_ERRORはゼロ)または失敗しました(SO_ERRORは、ここにリストされている通常の
エラーコードの1つであり、失敗の理由を説明しています)。
 
31
ninjalj