22

ノンブロッキング接続を作成したい。このような:

socket.connect(); // returns immediately

このために、別のスレッド、無限ループ、および Linux epoll を使用します。このように(疑似コード):

// in another thread
{
  create_non_block_socket();
  connect();

  epoll_create();
  epoll_ctl(); // subscribe socket to all events
  while (true)
  {
    epoll_wait(); // wait a small time(~100 ms)
    check_socket(); // check on EPOLLOUT event
  }
}

サーバーを実行してからクライアントを実行すると、すべて機能します。最初にクライアントを実行し、しばらく待ってからサーバーを実行すると、クライアントが接続しません。

私は何を間違っていますか?多分それは別の方法で行うことができますか?

4

3 に答える 3

46

非同期接続には次の手順を使用する必要があります。

  • でソケットを作成しますsocket(..., SOCK_NONBLOCK, ...)
  • との接続を開始connect(fd, ...)
  • 戻り値が 以外の場合、0エラーEINPROGRESSで中止されます
  • fd出力の準備ができたという信号が送られるまで待つ
  • ソケットのステータスを確認するgetsockopt(fd, SOL_SOCKET, SO_ERROR, ...)
  • 終わり

ループなし - 処理したくない場合を除きますEINTR

クライアントが最初に開始された場合ECONNREFUSED、最後のステップでエラーが表示されます。このような場合は、ソケットを閉じて最初からやり直してください。

詳細を確認しないと、コードの何が問題なのかを判断するのは困難です。操作のエラーで中止しないと思いますcheck_socket

于 2013-07-21T08:39:27.473 に答える
7

ノンブロッキング接続が成功するかどうかをテストするには、いくつかの方法があります。

  1. 最初に getpeername() を呼び出します。エラー ENOTCONN で失敗した場合、接続は失敗しました。次に、getsockopt を SO_ERROR で呼び出して、ソケットで保留中のエラーを取得します。
  2. 長さ 0 の read を呼び出します。読み取りが失敗した場合、接続が失敗し、read の errno が接続が失敗した理由を示します。接続が成功した場合、read は 0 を返します
  3. connect を再度呼び出します。errno が EISCONN の場合、接続は既に接続されており、最初の接続は成功しています。

参照: UNIX ネットワーク プログラミング V1

于 2019-04-12T09:40:11.270 に答える