3

生のソケット (ICMP パケット用) からデータを読み取る Linux で C/C++ アプリケーションを作成しています。質問: ソケットでまだキューに入れられているすべてのデータを破棄する方法はありますか?

問題は、しばらくスリープした後、興味のないデータがソケットにキューに入れられていることです。select()/recvfrom() ループに入ると、最近受信したデータのみを取得できるように、ソケットに「現在バッファリングしたすべてのデータを忘れる」ように指示するのが最善です。

最初に別の poll()/recvfrom() ループに入るよりも良い方法はありますか? おそらくいくつかのソケットAPI呼び出し?ポータブルでも?:-)

4

7 に答える 7

5

アイドル時間中は、受信バッファ サイズをゼロに設定することでソケットを無効にできます。

 int optval = 0; /* May need to be 1 on some platforms */

 setsockopt(sockDesc, SOL_SOCKET, SO_RCVBUF, (char *)(&optval), sizeof(optval));

"optval" をより大きなバッファ (4096 など) に設定して再度有効にします。

于 2008-10-21T12:41:40.797 に答える
2

まったく寝ないことをお勧めします。選択呼び出しを使用して、データが到着したらすぐに処理するように設定されています。

while (1)
{

    FD_ZERO (&sockets);
    FD_SET (raw_socket, &sockets);

    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    if (select (raw_socket + 1, &sockets, NULL, NULL, &timeout))
    {
    if (FD_ISSET (raw_socket, &sockets))
    {
        // handle the packet
    }
    }
    else
    {
    /* Select Timed Out */
    fprintf(stderr, "Timed out");
    }
}  

また、raw ソケットを作成するときに、icmp パケットのみに関心があることを指定できます。

于 2008-10-23T08:00:22.640 に答える
1

確実に行う方法を知っている唯一の方法は、ソケットを閉じることです。

于 2008-10-16T17:00:42.070 に答える
1

recvfrom()一時バッファーに a を実行して、バッファーを破棄することはできませんか?

于 2008-10-20T21:14:38.513 に答える
0

ミドルウェアアプリケーションの標準的な手順は、他のアプリケーションスレッドよりも高い優先度に設定されたIO要求を処理するための専用スレッドを用意することです。IOスレッドはパケットを受信すると、それをアプリケーション層にエンキューします。アプリケーションに空き時間があれば、次のパケットをデキューします。

これは、多くのリアルタイム市場データやエンタープライズメッセージングシステムで使用されているTIBCORendezvousの背後にあるアーキテクチャです。注意点は、通常、アプリケーションがOOMマネージャーによって取得されないように、キューサイズにある程度の制限が必要なことです。IOスレッドとアプリケーション層の間のプロトコルは、単純な非同期キューから、より複雑なサブジェクトフィルタリング、優先順位リスト、および着信データを並列にデコードするためのスレッドプールのサポートまでさまざまです。

于 2010-08-18T09:53:24.597 に答える
0

私は試していませんが、パフォーマンス上の理由からはまったく賢明ではないかもしれません (ただし、アプリがスリープ状態になる場合は問題にならない可能性があります)。ただし、スリープの前にソケットの受信バッファーを非常に小さな値に設定してみてください。これにより、アプリケーションがリッスンしていないときに到着するデータをソケットがバッファできなくなることを願っています。それは一種のロングショットです。

あるいは、スリープ後に受信バッファ サイズをリセットすると、再度読み取りを開始する準備ができたときに、それもフラッシュされます。もちろん、これらの種類のトリックはそれだけであり、機能したとしても、移植性がないことは間違いありません。アイデアを共有したいと思っただけです。テストする機会があれば、役立つかもしれません。

于 2008-10-17T13:45:14.337 に答える
0

寝る直前にこんなことできる?

for(n=0;n<=MAX_BUFFER_SIZE;n++)
{
recv_buffer[n] = 0;
}
于 2008-10-20T21:09:23.267 に答える