私のアプリケーションはTCP接続を作成しますが、これは正常に機能しています。しかし、1つのネットワークサーバーには多くのIPがあります。
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;
}
あなたの情報に基づいて:
54.x.x.x
にconnect()
を実行しようとしています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 と呼ばれます。
これは connect() の動作のようです:
接続をすぐに確立できず、ソケットのファイル記述子にO_NONBLOCKが設定されている場合、connect()は失敗し、errnoを[EINPROGRESS]に設定しますが、接続要求は中止されず、接続は非同期で確立されます。同じソケットに対する後続のconnect()の呼び出しは、接続が確立される前に失敗し、errnoを[EALREADY]に設定します。