SO_KEEPALIVE オプションの意義? – プログラミング – Home

SO_KEEPALIVE オプションの...
 
通知
すべてクリア

[解決済] SO_KEEPALIVE オプションの意義?


るし
 るし
(@るし)
ゲスト
結合: 16年前
投稿: 19
Topic starter  

お世話になります。
CAsyncSocketを使っています。SO_KEEPALIVEオプションについて使う意義?があるのか
疑問なのですが、皆さんは使用されていますでしょうか。

MSDNでは以下の説明があります。
 SO_KEEPALIVE 接続保持パケットを送信します。

いろいろなサイトで調べてたところ、TCP/IPのKEEPALIVEは2時間無通信状態が続いた場
合に特殊なパケットをピアに送信して応答を確認し、応答がない場合はコネクションを
クローズするとありました。意味のない資源をOSに自動で返却するための検出手段?と
いう解釈でよろしいのでしょうか。

TCPセッションを保持する目的では使えませんよね。解釈の間違いや他の使用目的などあ
りましたらご教示のほど、お願いいたします。


引用未解決
トピックタグ
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 18年前
投稿: 178
 

>疑問なのですが、皆さんは使用されていますでしょうか。

CAsyncSocketは使用していません(というかMFC使ってません)が、SO_KEEPALIVE使ってい
ません。
setsockopt()で変更はしていませんね。
WinSockがデフォルトでSO_KEEPALIVEを設定していれば使っていることになりますが…。
SO_KEEPALIVEの動作には全く期待していません。
メールチェッカーですが、2時間無通信になる前にサーバ側から切られるでしょうし。

>TCPセッションを保持する目的では使えませんよね。

おそらく使用できないでしょう。
上のレイヤで考慮すべきかと。


返信引用
み
 み
(@み)
ゲスト
結合: 16年前
投稿: 4
 

最近、SO_KEEPALIVEを使う機会がありました。

無通信のまま2~3日放置しておくと通信が切断されてしまうという症状が
SO_KEEPALIVEで強制的に通信を発生させることで改善されました。
つまり、相手が無応答になっているときの切断(応答確認)に使うのではなく、
長期間の無通信で勝手に切断されてしまうのを回避するのに使っています。
そもそも、KEEPALIVEって後者の意味ではないのかな?

教えて、誰か詳しい人。


返信引用
るし
 るし
(@るし)
ゲスト
結合: 16年前
投稿: 19
Topic starter  

お世話になります。ご回答、ありがとうございます。

>長期間の無通信で勝手に切断されてしまうのを回避するのに使っています。

長期間というのがポイントなのかなと思います。Windowsの場合、keepaliveで特殊パケ
ットが送信される間隔は標準で2時間と聞いています。み様のように2、3日で切れる
ようなシステムにおいては2時間毎にトラフィックが発生する為、セッションがキープ
される方向に働いているのかなと想像します。

モバイルカードを装備したノートパソコンに対してデータを送信するシステムを作った
ことがありますが、IPSECを使用した場合に5分でセッションが切断されてしまう現象に
遭遇しました。この時、keepaliveオプションも使用してみたのですが、期待通りの動き
にはなりませんでした。5分以下で定期的にトラフィックを発生させることでセッション
が継続されましたが。

>そもそも、KEEPALIVEって後者の意味ではないのかな?

私もそうあってほしいと思ったのですが、現状では2時間以上、以下で期待できる動きが
違うように思います。

ソケット毎にKEEPALIVE時間を変更するというページも見つけました。

http://www.jurabi.jp/blog/?p=12

まだ実験できてないのですが、試したらレポートします。
でも、これってCAsyncSocketで使えるのかなぁ^^;


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

うーん、
間にサーバがからんでいると判断が難しいのでは?
まず、サーバもなしにPC同士クロスケーブルで繋いで通信を再現できますか?
それで同じように2時間でエラーになるのでしょうか?
もしエラーにならないのなら、サーバとの対応になると思います。
サーバ側で混雑を回避するためにタイムアウトを設けていることも考えられます。


返信引用
るし
 るし
(@るし)
ゲスト
結合: 16年前
投稿: 19
Topic starter  

ITO様
ご回答、ありがとうございます。

>間にサーバがからんでいると判断が難しいのでは?
どこの部分に対するコメントかちょっと判断しかねたのですが、モバイル通信における
通信キャリアのサーバとか、ルータというような解釈でいいですか?

>5分以下で定期的にトラフィックを発生させることでセッション
この部分についていえば業務的なトラフィックではなくたんに定期的にPINGを打っただ
けです。また、ノートパソコン側は自前のソケット通信モジュールであり、業務的に切
断する要素は何もありませんでした。

業務的な部分はさておき、単純なTCPサーバ、クライアント間でKEEPALIVEがどういう動
きになるか試してみようと思います。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

> どこの部分に対するコメントかちょっと判断しかねたのですが、モバイル通信に
> おける通信キャリアのサーバとか、ルータというような解釈でいいですか?
間に、会社関連のサーバがからんでないかと思ったのですが、なさそうですね。
モバイル通信関連は詳しくないのですが、無線LANのようになるんですよね?
そのへんでのハードがらみのタイムアウトとかは大丈夫ですか?
PINGを打つとウイルスソフトが排除する可能性があります。確認してみたほうが
いいですね。


返信引用
るし
 るし
(@るし)
ゲスト
結合: 16年前
投稿: 19
Topic starter  

簡単なTCPサーバ、クライアントでテストを実施してみました。
※非同期ソケットクラスを使用。

[1]--------[RT]----------[2]
s <--------------------- c  (KEEPALIVE有)
c ---------------------> s

1 :XPノートパソコン
2 :VISTAデスクトップパソコン
RT:ADSLルータ(自宅なので^^;)

s:TCPサーバ
c:TCPクライアント

※TCPサーバはListen待ち受け状態において、クライアント側からのconnect要求により
 接続されたTCPソケットとします。

上図のように2本の通信パスを作成します。
※接続後は、サーバおよびクライアント間でアプリケーションデータの送受信は発生し
ません。

端末2側のTCPクライアントはKEEPALIVEを設定します。

次に端末1側のネットワークケーブルを切断します。

[1]×-------[RT]----------[2]

この時点で端末1側のTCPサーバおよびTCPクライアントはソケットクローズを検出しま
した。以降、端末1は試験に関係ないので置いときます。

端末2側ではRTの向こうの物理切断は検出できないので、サーバ、クライアントともに接
続したままの認識になってます。

さて、この状態で2時間まってみました。結果としては、2時間に数分たらない時間で、
端末2のTCPクライアント側がネットワーク切断を検出し、ソケットをクローズしまし
た。KEEPALIVEにより送信された特殊パケットに対する応答がないため、切断が検出され
たみたいです。TCPサーバ側はKEEPALIVEを設定してなかったので接続しているものと誤
認識したままでした。
このケースはKEEPALIVEが切断の検出機構として働く例といえますね。

ネットワークの知識は乏しいので、以下、間違いだらけな推測かもしれませんが。
み様のケースで、2端末間のネットワーク経路上に一定の無通信状態でセッションを切断
する要素があるのではないかと想像します。たとえば、

[1]--------[RT]----------[2]

上記のRTが無通信監視をしていて、2~3日の無通信状態でセッションを切断するような
機構(そんなのあるかな?^^;)があったとします。
KEEPALIVEを設定した場合、端末1と端末2の業務に関係ないレベルでパケットの送受信
が2時間ごとに発生します。その結果、RTから見ると無通信状態ではないため、セッショ
ンが切断されることはなくなります。
過去の私のケースでいえば無通信監視するのは端末1、2に設定したIPSECであり、RTは
通信キャリア部分に該当します。

今回の試験でKEEPALIVEの動きが自分なりにだいぶ見えてきましたが、ほかの見識などお
持ちのかたがいらっしゃいましたらぜひお聞かせください。

以上


返信引用
るし
 るし
(@るし)
ゲスト
結合: 16年前
投稿: 19
Topic starter  

クローズしておきます。
ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました