1. ホーム
  2. c

[解決済み] 接続(関数)エラーでオペレーションが現在進行中エラー

2022-02-10 02:06:38

質問内容

接続関数のタイムアウト値を設定したいのですが、「"Operation now in progress"」というエラーが表示されます。

私のコード

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() マンページ :

EINPROGRESS

    ソケットがノンブロッキングであるため、接続を完了できない
    をすぐに実行します。 select(2)やpoll(2)で完了させることは可能です。
    書き込み用ソケットを選択する。 select(2) が
    書き込み可能な場合は、getsockopt(2) を使用して、SO_ERROR オプションをレベル
    SOL_SOCKETで、connect()が正常に終了したかどうかを判断します。
    (SO_ERRORは0)または失敗(SO_ERRORは通常の
    エラーコードはここに記載されており、失敗の理由を説明しています)。