0

コードシンペット:

int CreateaTCPSocket()
{
    int iSockID =  ACE_OS::socket(......);
    ACE_OS::set_flags(iSockID,O_NONBLOCK);
    ACE_OS::bind();
    if (ACE_OS::connect(iSockID ,....) < 0)
    {
        if (ACE_OS::select(.....,timeout) <= 0)
        {
            return INVALID_HANDLE;
        }
    }
    return iSockID;
}

私の質問は、非ブロックエラーのために接続が失敗し、selectが呼び出され、select return successと言うと、もう一度connectを呼び出すか、関数internal do connectを選択する必要がありますか?

4

2 に答える 2

3

ブロッキングソケットと非ブロッキングソケットの両方で、呼び出す必要があるのはconnect()1回だけです。

ソケットが非ブロッキングでconnect()戻っEINPROGRESSてきたら、ソケットが。を使用して書き込みの準備ができるまで待つ必要がありますselect()select()ソケットが書き込みの準備ができていることを報告するとき、それはconnect()成功したか失敗したかのどちらかである可能性があります。

非ブロッキングconnect()が成功したかどうかを確認するにはgetsockopt(..., SOL_SOCKET, SO_ERROR, ...)、失敗時にゼロ以外のエラーを報告する呼び出し、またはgetpeername()接続されたソケットでのみ成功する呼び出しを実行できます。

于 2011-01-17T11:56:29.887 に答える
0

接続に失敗したらselectを呼び出すのはなぜですか?それで何を達成したいですか?selectは、引数として指定されたリソースのアクティビティを呼び出し元に通知します。これらの活動は

  • エラー(例:tcpソケット:ピアが切断されました)
  • 利用可能なデータ(実際にブロックせずにブロック読み取りを実行できます)
  • 書き込み可能(最後の書き込みがバッファいっぱいで失敗した後)

あなたが説明したシナリオでは、記述子がまだoopedされていないか、すでに閉じられているため、selectは常にEBADFを返します(私が知っている一部のOSでは)。

hth

マリオ

于 2011-01-17T11:57:36.150 に答える