y_kudo_ncpl
2016年12月19日 11時52分
工藤@NCPLと申します。
Armadillo440 のUSBポートに弊社装置に接続して、Ethernet⇔USBの変換機のような使い方をしています。
TCPのKeep-Aliveの挙動について教えてください。
切断検出のため,KeepAliveを使っております。
目論見としては10秒後から1秒間隔でKeepAlive、10回で応答が無ければ切断なのですが
実際に動作させたところ、
・10秒後から10秒間隔で送信。
・3回の送信後、WireSharkで観察すると応答が返っているように見えているにも関わらずArmadillo側から切断
(WireSharkのスクリーンショットを添付します。192.168.0.3がArmadillo,192.168.0.20がPCです。)
という、思惑と異なる挙動が出て、原因を探しております。
以下はソースコード当該箇所の抜粋です。
設定の間違い、あるいは設定の漏れがあるのでしょうか?
define KEEPALIVE_DELAY 10 #define KEEPALIVE_INTERVAL 1 #define KEEPALIVE_ERRCOUNT 10 /*Ignore SIGPIPE これをやらないと相手にクローズされた後読み書きするとプロセス落ちる*/ /*またはちゃんとハンドラを定義する。*/ signal(SIGPIPE, SIG_IGN); /*リッスンソケット作る*/ sock0 = socket(AF_INET, SOCK_STREAM, 0); if( sock0 == -1 ){ perror( "socket error:"); return errno; }; on = 1 ; //ReUse可能 if (setsockopt (sock0, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { perror( "setsockopt (sock0, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)):"); return errno ; }; on = 1; //KeepAlive if(setsockopt (sock0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) { perror( "setsockopt (sock0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)):"); return errno ; }; option = KEEPALIVE_DELAY; //秒後からKeepAliveする setsockopt( sock0, IPPROTO_TCP, TCP_KEEPIDLE, (void*)&option, sizeof(option) ); option = KEEPALIVE_INTERVAL; //秒間隔でKeepAliveする setsockopt( sock0, IPPROTO_TCP, TCP_KEEPINTVL, (void*)&option, sizeof(option) ); option = KEEPALIVE_ERRCOUNT; //回KeepAlive失敗したらエラーにする setsockopt( sock0, IPPROTO_TCP, TCP_KEEPCNT, (void*)&option, sizeof(option) );
以下略
ファイル | ファイルの説明 |
---|---|
キャプチャ.PNG | WireSharkのスクリーンショット |
コメント
y_kudo_ncpl
n.yamamoto
Yamamotoです。
横から失礼します。
”ソケット接続が出来なくなる ”件の関連で気になったので投稿しました。
”ソケット接続が出来なくなる ”件で、同じようにAccept前(Socket生成直後)にKeepAliveの設定をしているのですが、Accept前に行っているとソケットが接続できなくなる現象を引き起こしたりすのでしょうか?
Wiresharkで見ると双方からFIN+ACK送信後(双方で切断完了しているはず)にKeepaliveが送信されて、無くなったソケットに接続確認を繰り返してからRST+ACKでリセット送信されています。
あとクライアント側でのconnect接続時も、connect前(Socket生成直後)にKeepalive設定を行っているのですがこれも良くないのでしょうか?
ご意見をお聞かせください。
at_yashi
2016年12月19日 14時37分
こんな感じで動いているようです。
accept()
する前のソケットで設定してたりしますか?# 次から、compileできるコードを貼ってもらえると助かります。
tcpdump の表示