RX65N+FreeRtos+T4でtcp切断を実行する時の動作について

初めまして。YIと申します。

RX65N+FreeRtos+T4 (e2studio,GCC)でエコーサーバを動作させています。

(サンプルのrskrx65n_2mb_tcp_nonblockingをベースにしました)

ほぼ、動作しているのですが接続⇒受信⇒送信⇒切断を何度も繰り返し実行すると

時々切断が異常になります。

tcp_sht_cep 又は tcp_cls_cep 関数から戻らないことがあります。

この時クライアント側は正しく終了しています。

Wiresharkでデータを確認しましたが正常時と同じでした。

試しにソース上から tcp_sht_cep を削除して tcp_cls_cep のみにすると今のところ異常は発生していません。

この時も、Wiresharkでデータを確認しましたが正常時と同じでした。

これらをデバッグする方法等、ご存じでしたら教えてください。

また、tcp_sht_cep は無くても良いものなのでしょうか。

以上、よろしくお願いいたします。

Parents
  • YIさん

    シェルティです、こんにちは。ルネサスの中の人です。T4の設計をしました。

    tcp_sht_cep()は必ず戻ってくる仕様で、tcp_cls_cepは第2引数が TMO_FEVR ならクローズ完了するまで永久待ちで戻ってこないパタンがあります。とはいえ、tcp_cls_cep()もデフォルトで10分間の間クローズに失敗し続ける(厳密にはFINパケットに対するACKが検知できないまま10分経過)とAPIから戻ってきます。

    今回のケースだとtcp_sht_cep()を呼び出してTIME_WAIT状態になっているのでは、と思いますがどうでしょう。こちらはデフォルトで1分タイマにて状態がCLOSEDになり、tcp_cls_cep()から抜けてきます。

    TCPの状態遷移図は以下が参考になります。

    【図解】TCPの状態遷移 〜Listen、Establish、FIN Wait等〜 | SEの道標 (nesuke.com)

    tcp_sht_cep()が無くてもよいかというとYESですね。tcp_sht_cep()はFINを出力するだけのAPIです。FINは「送信完了」の意味で切断の意味ではなく、実は受信はできます。なので「送信はしないけど、受信はしたい」というケースでtcp_sht_cep()が使われます。だいたいのケースでは自分が送りたいデータを送ったらもうあとは切断するだけ、ということになると思うのでその場合はtcp_cls_cep()だけで事足ります。tcp_cls_cep()はFINを送ったあとCLOSEDに遷移するまで待ち状態を作ることができます。

    TCPは切断シーケンスが若干ややこしいので以下にはまりどころを説明します。

    自分がFINを送ったときに通信相手がまだFINを送ってきてなければFIN_WAIT1になりやがてTIME_WAIT状態で1分待ちになります。自分がFINを送ったときに通信相手がFINをすでに送ってきている場合はCLOSE_WAITになりACKが戻ってきたらすぐCLOSEDに遷移します。CLOSEDに遷移するとtcp_cls_cep()はプログラムカウンタを戻します。(あるいはタイムアウト指定でTMO_NBLK(ノンブロッキングコール)にするとコールバック関数が呼ばれます)

    このTIME_WAIT状態になっているとデフォルトで1分間APIから抜けてこないような動作になるので不具合に見えますが正常動作です。もしTIME_WAIT状態の待ち時間を変更したい場合はtcpudp_config.cの以下変数値(_tcp_2msl)を変更してください。

    https://github.com/renesas/rx-driver-package/blob/bfac1edd52bd040126dbc5c95ed16d95289c0c30/source/r_t4_rx/r_t4_rx_vx.xx/r_t4_rx/ref/config_tcpudp_reference.tpl#L156

    以上です

  • シェルティ様

    YIです。初めまして。

    早速の回答ありがとうございます。

    _tcp_2mslの変更を試してみます。

    以上、よろしくお願いいたします。

Reply Children
No Data