質問: websocketについて学ぶためにcwebsocketというCのwebsocketライブラリのコードを読んでいます。 READMEにある通り、この実装ではpayloadの大きさが0xFFFFより大きいフレームをサポートしていません。 > > Not supported > ------------- > > > big frames, which payload size bigger than 0xFFFF > > > 仮にこのライブラリをどんな大きさのフレームにも対応させるにはどうすればいいのでしょうか? 考えられるやり方としては 1. フレームの最初の16bitを受け取る 2. 受け取った16bitの中の後ろ7bitを確認 3. 2での値によってpayload長のbit数が違うのでその分をmallocで確保してrecvする 4. payloadの長さがわかったらその大きさの量をmallocして読み込む という方法がありますがmallocが何度も起こってしまいます。 他に良い方法はないのでしょうか?
回答: 3はそもそもmallocが必要ではないと思います.最初から必要な領域を(ヒープではなく)スタックに確保しておくのはどうでしょうか. つまり最大payload長を収容できる64bit分の領域`char paylen[8]`をスタックに用意しておいて,最初の7bitを`paylen[0]`で読んでから,`paylen[0]`が`126`の場合はさらに続きの16bitを`paylen[0]`と`paylen[1]`に読み込みこみます.また,`127`の場合は続きの64bitを`paylen[0]`から`paylen[7]`に読み込みます. その後ビット操作によって`paylen`を`int64_t`型変数に変換します. ``` //126の場合 int64_t payload_length = (int64_t)paylen[0] << 8 | paylen[1]; ``` 4で起こるmallocついては,一度mallocした領域を使いまわして,それよりも大きい領域が必要になった場合にのみ新しく確保して古い領域を開放するというやり方で回数を減らせると思います. こうすると過去のpayload長を超えないデータについてはmallocが必要なくなるというわけです. もしこれでメモリ使用量が問題になる場合は適当なタイミングや容量制限を設けて領域を開放してやればいいでしょう. ただ,mallocが本当にパフォーマンスに影響するかどうかは実装してみないと分からない部分があると思います.なので,4についてはまずmallocを愚直に使ってきちんと動作するコードを完成させた後に,プロファイリングを行ってmallocの回数が問題であることを証明してから,こういったトリックを導入することをお勧めします.