web-dev-qa-db-ja.com

TCP接続エラー115操作が進行中原因は何ですか?

私のアプリケーションはTCP接続を作成しますが、これは正常に機能しています。しかし、1つのネットワークサーバーには多くのIPがあります。

  • 174.X.X.X
  • このような54.x.x.x

TCP=タイムアウト(60秒のタイムアウトによる非ブロッキング)をIPに接続する場合174.X.X.Xは常に成功です。しかしTCP ipで同じサーバーに接続する54.x.x.xは失敗し(ほとんどの場合)、errno 115の測定操作が進行中です。

Errno 115の考えられる理由を教えてください。

OS:Linux

私のTCP接続コードは以下の通りです

tcp_connect(......)
{

  int iValOpt = 0;  
  int iLength= 0;

  fcnt((int)(long)SockID,F_SETFL_O_NONBLOCK);

  ret = connect (sockID,(struct sockaddr*)pstSockAdr,uiSockLen);

  if (ret < 0)
  {

        if (errno == EINPROGRESS)
        {
                stTv.tv_sec = 60;
                stTv.tv_usec = 0;
                FD_ZERO(&write_fd);
                FD_SET(sockID,&write_fd);

                iLength = sizeof(int);

                if (0 < select (sockID+1) , NULL,&write_fd,NULL,&stTv);

                {
                        if(0 > getsockopt(sockID,SOL_SOCKET,SO_ERROR,(void*)(&iValOpt),&iLength))
                        {
                                return -1
                        }

                        if (0 != iValOpt)
                        {
                                return -1;
                        }


                        return success;
                }

                else
                {
                        return -1;
                }   

        }
        else
        {
                return -1;
        }
    }

   return success;

}
15
user1340512

あなたの情報に基づいて:

  • 54.x.x.xconnect()を実行しようとしています
  • ソケットはnon-blockingです
  • 接続タイムアウトは60 secです

まず、/usr/include/asm-generic/errno.hを確認すると、次のように表示されます。

#define EINPROGRESS     115     /* Operation now in progress */

これは、ソケットの既存の操作が進行中であることを意味します。 connect()呼び出しを行っていると言ったので、 man connect を実行してみましょう:

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

したがって、TCP 3ウェイハンドシェイク(54.x.x.x IPアドレスへのconnect()呼び出し)が完了するまでに予想以上に時間がかかると考えられます。 connect()操作はすでに進行中です。その後のソケットでの操作は、EINPROGRESSエラーコードになります。manページで提案されているように、select()またはpoll()を使用して、ソケットが使用できるかどうかを確認します(read()またはwrite()呼び出しを実行するため)。

自分のマシンと54.x.x.xとの間のトラフィックをキャプチャして分析することで、TCPハンドシェイクの完了を妨げている原因を特定できます。これを支援する最適なツールは、 WireShark と呼ばれます。

TCP 3 way handshake

22
gsbabil

これは connect() の動作のようです:

接続をすぐに確立できず、ソケットのファイル記述子にO_NONBLOCKが設定されている場合、connect()は失敗し、errnoを[EINPROGRESS]に設定しますが、接続要求は中止されず、接続は非同期で確立されます。同じソケットに対する後続のconnect()の呼び出しは、接続が確立される前に失敗し、errnoを[EALREADY]に設定します。

6
Anders Lindahl