7872


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

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

[code]

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

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

[code]

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

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

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


CC BY-SA 3.0
2015-03-13T06:28:03.247
7867
2015-03-13T07:12:19.383
3496
question
c http network socket tcp
1回のソケットのsend()やssl_write()で送るバイト数の適切サイズ


TCP/IPの通信の効率化を考える場合には、  
送信データサイズについて

1.「遅延(Delayed)ACK (RFC1122)」  
2.「Nagleアルゴリズム (RFC896)」

を考慮すべきだと考えられます。  
おおざっぱにいうと、どちらも小さなサイズのパケットが  
多数発生することを抑えるための仕組みといえます。  
従って、送信時には概ね1500Byteより大きなパケットで送った方が良い結果が得られます。  
大きすぎるデータ送信は他に迷惑がかかりますが、閉じたネットワークならば  
大きな問題にはならないかもしれません。


CC BY-SA 3.0
2015-03-13T06:48:25.767
7870
2015-03-13T06:48:25.767
3793
7867
answer


適切なサイズというのは環境に依存するので回答は難しいと思います。

一般的に言って、バッファサイズに余裕があるなら、まとまった量のデータをわざわざ小分けにして送るメリットはありません。適切なセグメントサイズへの分割は自動で行われますし、[Nagleアルゴリズム](https://ja.wikipedia.org/wiki/Nagle%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0)が有効な場合は小分けにしてもまとめて送信されます。


CC BY-SA 3.0
2015-03-13T06:49:48.417
7871
2015-03-13T06:49:48.417
3639
7867
answer


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

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


CC BY-SA 3.0
2015-03-13T06:50:01.057
7872
2015-03-13T07:12:19.383
2015-03-13T07:12:19.383
799
799
7867
answer