2011-08-04 7 views
0

LinuxでTCPソケットからデータを取得するインターフェイスを作成しています。ユーザは、受信したデータが格納されるバッファを提供する。提供されたバッファが小さい場合、私はエラーを返すだけです。 最初の問題は、バッファーが小さいかどうかを判断することです。 recv()関数はバッファに実際に書き込まれたバイト数を返します。 recv()のマンページに記載されているMSG_TRUNCフラグを使用すると、それでも私には同じものが返されます。 2番目の問題は、まだソケットに入れられているデータを破棄することです。私の提供するバッファが小さくて済むと判断したら、ソケットに残っているものをすべて消去したいだけです。閉じてソケットをもう一度開くか、何も残らないうちに受信する以外の方法はありますか? よろしくソケットにデータが残っているかどうかを確認して破棄します。

トビー

答えて

1

manページに記載されているように、MSG_TRUNCは、パケットのソケット(例えばUDP)に対してのみ有効ですので、あなたはストリームベースであるあなたのTCPソケット用にしたいので、これは動作しません。文字通りstackoverflowやTCPのアプリケーションメッセージの境界を保持することについてのヒントは何百もあります(ヒント:これはあなた自身が行う必要があります。TCPはバイトストリームインターフェイスですが、そうではありません)のでここでは詳しく説明しませんそれは、あなたがTCP(またはUDPに切り替える必要がある)の上で必要なことを可能にするために、recv()側にアプリケーション "メッセージ"または "パケット"がどのくらいの大きさであるかを知るためのメカニズムが必要であるということです。 。

TCPの場合、ソケットを "ドレイン"にする必要がある場合は、データが残っていない状態になるまで読み込みますが、上記のメッセージ境界を考慮して1つの "メッセージそして、次のものに食べることを覚えておいてください。もう一度、TCPがバイトストリームインターフェイスを提供し、必ずしもアプリケーションレベルのパケットやメッセージの概念を保持するわけではありません。

+0

[tcp(7)のマニュアルページ](http://man7.org/linux/man-pages/man7/tcp.7.html)によると: "* 2.4以降、Linuxでは' 'recv(2)'(および 'recvmsg(2)')の 'flags'引数に' MSG_TRUNC'を指定すると、受信したデータのバイトが、呼び出し元のバッファに返されるのではなく、破棄されます。 2.4.4、 'MSG_TRUNC'は' MSG_OOB'と一緒に使用して帯域外データを受信するときにもこの効果を発揮します* –

関連する問題