1回のソケットのsend()やssl_write()で送るバイト数の適切サイズ


ソケットの一回の送信で適切なサイズはありますか？

たとえば65535バイト送信したいとします。  
下記のように全て送るか、

[code]

    socket.send(buf, 65535);
    
[/code]

下記のように小分けに送るか

[code]

    socket.send(buf, 2048);
    // bufを2048進めて繰り返す
    
[/code]

また、適切なサイズがあったとして  
OpenSSLのssl_write()の場合は事情が少し違うなどの情報もありましたら教えていただけると助かります。

個人的にはTCPの(イーサネットを考慮した)1セグメントは1460バイトらしいので、1460以上の場合は1460単位で分割して送るのが良いような気がしています。




TCPの場合、大きなデータを適切な小断片(MSS:最大セグメントサイズ)へ分割する仕事は、TCP層が行ってくれます。もし20MB送りたければ、20MB渡してしまってよいです。アプリケーションレベルで小分けに送信呼び出しをすると、システムコール呼び出しがそこそこに時間を要するために、性能上のデメリットだけがあります。

UDPの場合は分割機能を持ちませんので、性能が大事なケースではアプリケーションで考えて分割送信する意味はあります。もし経路上で転送可能なサイズ(MTU)より大きいサイズの送信要求を出した場合、下層がIPであればIP層で分割・結合が行われるのですが、これは断片の一つでも失われたら全て廃棄するルールなので、大変よろしくないです。(IPフラグメンテーション)  
余談ですが、具体的な分割後サイズは、その1460Byteの例のような標準的ヘッダサイズ計算によって求めるのは不適切です。PPPoEを経由するとか、モバイルネットワークの都合とかで、もうちょっと小さくなっているケースは珍しくありません。




TCPの場合、大きなデータを適切な小断片(MSS:最大セグメントサイズ)へ分割する仕事は、TCP層が行ってくれます。もし20MB送りたければ、20MB渡してしまってよいです。アプリケーションレベルで小分けに送信呼び出しをすると、システムコール呼び出しがそこそこに時間を要するために、性能上のデメリットだけがあります。

UDPの場合は分割機能を持ちませんので、性能が大事なケースではアプリケーションで考えて分割送信する意味はあります。もし経路上で転送可能なサイズ(MTU)より大きいサイズの送信要求を出した場合、下層がIPであればIP層で分割・結合が行われるのですが、これは断片の一つでも失われたら全て廃棄するルールなので、大変よろしくないです。(IPフラグメンテーション)  
余談ですが、具体的な分割後サイズは、その1460Byteの例のような標準的ヘッダサイズ計算によって求めるのは不適切です。PPPoEを経由するとか、モバイルネットワークの都合とかで、もうちょっと小さくなっているケースは珍しくありません。

