1

私は、すべてのピアが互いに通信するp2pソフトウェアのように機能するアプリケーションを持っています。通信はTCPになるので、複数の接続を処理できるようにepool(4)を使用できると思いました。各ピアは非常に頻繁にデータを送信するため、アプリケーションの存続期間中に使用される各ピアへの永続的な接続を確立すると思いました。

さて、処理方法がわからないことの1つは、接続が閉じられないため、データの受信を停止し、さらにパッケージをリッスンするために再度read()呼び出すタイミングをどのように知ることができるかということです。epool_wait()または、永続的なTCP接続を処理するためのより良い方法はありますか?

4

3 に答える 3

2

ソケットを非ブロッキングに設定する必要があります。epollが読み取るデータがあることを示したら、read()が-1を返し、errnoがEWOULDBLOCKになるまで、ループ内でread()を呼び出す必要があります。

つまり、読み取りループは次のようになります。

for(;;)
  ssize_t ret;
  ret = read(...);
  if(ret == 0) {
     //client disconnected, handle it, remove the fd from the epoll set
      break;
  } else if(ret == -1) {
     if(errno == EWOULDBLOCK) {
        // no more data, return to epoll loop
      } else {
        //error occured, handle it remove the fd from the epoll set
      }
      break;
  }

 // handle the read data 
}

epollでエッジトリガーモードを使用していない場合は、ループは実際には必要ありません。1回の読み取りを行うだけで、epollループに戻ることができます。ただし、上記のコードと同じように戻り値を処理してください。

于 2010-03-03T18:01:13.957 に答える
1

それは「epool」ではなく「epoll」であるべきでした... epollに精通していませんが、「poll」を使用したソケットの例を見るためにBeejのガイドを見てください...そこのセクション7.2を見てくださいそれがどのように行われるかを見て、「投票」の使用法についてセクション9.17も見てください...

これがお役に立てば幸いです。よろしくお願いします、トム。

于 2010-03-03T14:16:18.550 に答える
0

read() は、すぐに利用できるデータを読み取ります (ただし、要求したデータを超えることはありません)。アクティブなソケットで read() を実行し、十分なバッファ (おそらく MTU よりも大きい必要はありません... 2048 バイトで十分です) を実行し、完了したら epoll_wait() を呼び出します。

于 2010-03-03T14:10:11.863 に答える