2016-12-22 13 views
1

私はクライアントアプリケーションからudpを介してデータを受信して​​いる私が取り組んでいるサーバーアプリケーション。ブーストASIO udp最適化の質問を

サーバーはudpデータを非同期で受信する必要があります。これを達成するには2つの一般的な方法があるようです。

方法1:

boost::array<char, 65000> recv_buffer; 
socket.async_receive_from(boost::asio::buffer(recv_buffer), senderEndpoint, handler); 

方法2(Variable-size buffer for receiving UDP packetsから):

socket.async_receive(boost::asio::null_buffers(), receive_handler); 

// in the handler code 
unsigned int available = socket.available(); 
buffer = resize_buffer_if_needed(available); 
unsigned int packetSize = socket.receive_from(boost::asio::buffer(buffer, available), senderEndpoint, 0, ec); 

私のニーズに、よりがちかもしれ方法を評価するのに役立つしてください。よろしく。

質問1:言及ポストから

、最初の内部バッファにデータを保存するためにASIOを起こし、その後、私のバッファにコピーするなどの方法2は非効率的である表示されます。これは正しいです?

は質問2:

クライアントがsocket.send_to().への単一の呼び出しで64K以上のデータを送信することはありません。これを考えると、方法1は常により良い選択ですか?

質問3:

私のサーバーへの攻撃を減らす方法を提供する必要があります。最初の2バイトをマジックキーとして使用することを考えていました。アイデアは、最初の2バイトが予想されるマジックキーでない場合、私はメッセージを無視するということです。これを考えると、方法2を使用する方が良いでしょうか?

質問4:私の設計では

、次の4つのバイトは、以下のバイナリデータの実際のサイズであることを行いました。しかし、socket.available()が既に私に長さを与えているとすれば、私は本当にこの情報を送る必要はないと思われます。長さは単にsocket.available()に頼っても構いませんか?

答えて

2
  1. いいえ最初に一時バッファに格納しません。 FIONREAD ioctlを使用して、カーネルのIPスタックバッファーにあるものを確認します。

  2. コードは単純であり、決してあなたはまだデータグラムソケットの本質である、一度に全部のパケットが送信されますので、ノー任意の動的割り当てに

  3. を行う必要があるので、私は、そう言うだろう。最大バッファサイズを守り、信頼できないデータの解析を避けるだけです。しかし、「魔法の数」はほとんど保護されていません。攻撃者が適応するのは非常に簡単です(65536通りの組み合わせしかありません)。パケットを認証するためにHMAC-sgin(または同様のもの)を持つ方がずっと良いです。

  4. まだUDPですので、バッチで受信することはほとんどありません(カーネルはそれほど多くのCPU負荷を同じレイテンシに追加するだけではありません)。また

    Q.私の設計では、次の4バイトが実際のバイナリデータのサイズになります。

    最初に認証に注意してください。信頼できないデータは解析しないでください。 Colin PercivalのEncrypt-then-MACを参照してください。

+0

Seheを参照してください。ご助力ありがとうございます。よろしく。 – Peter

関連する問題