2

このアプリケーションは、接続および選択操作(cコード)でノンブロッキングソケットを使用します。プセドコードは以下の通りです

unsigned int ConnectToServer(struct sockaddr_in *pSelfAddr,struct sockaddr_in *pDestAddr)
{
    int sktConnect = -1;

    sktConnect = socket(AF_INET,SOCK_STREAM,0);
    if(sktConnect == INVALID_SOCKET)
        return -1;


    fcntl(sktConnect,F_SETFL,fcntl(sktConnect,F_GETFL) | O_NONBLOCK);
    if(pSelfAddr != 0)
    {
        if(bind(sktConnect,(const struct sockaddr*)(void *)pSelfAddr,sizeof(*pSelfAddr)) != 0)
        {
            closesocket(sktConnect);
            return -1;
        }
    }


    errno = 0;
    int nRc = connect(sktConnect,(const struct sockaddr*)(void *)pDestAddr, sizeof(*pDestAddr));
    if(nrC != -1)
    {
        return sktConnect;
    }

    if(errno != EINPROGRESS)
    {
        int savedError = errno;
        closesocket(sktConnect);
        return -1;
    }

    fd_set scanSet;
    FD_ZERO(&scanSet);
    FD_SET(sktConnect,&scanSet);

    struct timeval waitTime;
    waitTime.tv_sec = 2;
    waitTime.tv_usec = 0;

    int tmp;
    tmp = select(sktConnect +1, (fd_set*)0, &scanSet, (fd_set*)0,&waitTime);
    if(tmp == -1 || !FD_ISSET(sktConnect,&scanSet))
    {
        int savedErrorNo = errno;
        writeLog("Connect %s failed after select, cause %d, error %s",inet_ntoa(pDestAddr->sin_addr),savedErrorNo,strerror(savedErrorNo));
        closesocket(sktConnect);
        return -1;
    }

    .   
    .   
    .
    .
    .}  

問題
の説明上記のコードでは、「操作が進行中」でselect失敗します。で失敗するerror code 115ことに関するドキュメントはありません。 selecterrno 115

a。非ブロッキングソケットでselect失敗するのはいつですか?error code 115どのようなシナリオで?
b。この問題を示唆するシステムログはありますか?私たちだけが心配している-そのような問題を説明する文書化された機能は見つかりませんでした。


PS:SUSE Linux 11EnterpriseEditionを使用しています。

4

3 に答える 3

2

errno EINPROGRESSはselect()からのものではなく、前のconnect()操作から残っています。select()が-1を返した場合、またはFDが設定されていない場合は、それを報告するブロックに入ります。これはすべて、接続がまだ進行中であることを意味します。errnoがクリアされることはなく、設定されるだけです。

于 2012-06-22T23:55:55.397 に答える
0

あなたのコードに関するいくつかの考え:

selectの下の条件は、selectが0より大きい値を返した場合にのみ確認するように変更できると思います。その場合は、ソケット(SOL_SOCKETおよびSO_ERRORの場合)オプションのgetsockoptの出力を確認できます(getsockopt(...,SOL_SOCKET, SO_ERROR,...,...))接続が失敗していないかどうかを確認します。

接続が成功した場合に、selectが常にソケットを書き込み可能として返すかどうかはよくわかりません。したがって、あなたの場合、tmp変数が-1ではなく、表示されているerrnoが前の接続呼び出しのerrnoである場合があります(可能性があります)。

その他の理由:

もう1つの理由は、接続している宛先アドレスに到達できないか、指定されたアドレスとポートの組み合わせで待機しているサーバーがないことです。その場合、ブロッキングソケットを使用して一度試して、接続されているかどうかを確認できます。

于 2012-06-22T06:42:12.940 に答える
0

私が理解している限り、あなたはタイムアウトで接続を確立しようとしています。

その場合、コードにエラーがあります。connect()呼び出し後、前に。を使用してオプションをselect()削除する必要があります。そうしないと、ソケット(を持っている)での操作がブロックされないため、は常に一度に戻ります。O_NONBLOCKfcntl()select()O_NONBLOCK

あなたが読んだEINPROGRESSは、おそらく前の呼び出しによってではselect()なく、前のconnect()呼び出しによって生成されています。

また、アドレスをソケットに暗黙的にバインドするbind()ため、ここでcallを使用しないでください。connect()

于 2012-06-22T07:00:55.533 に答える