こんにちは。
RX63Nで T4のFTPサーバ機能を動かしているのですが、LIST (ftpでdir)が終わらなくてエラーとなります。ファイル情報は送信されているのですが、その後の終了処理(tcp_cls_cep)以降の処理が旨く行ってないようです。 ちなみにFTPはこけてもpingには応答してますのでT4自身はそこでも動作してるようです。何かご存知の方しませんでしょうか? (ちなみにRI600使ってますが、通信端点ごとにタスクっているんでしょうか????)
こんにちは、シェルティです。
前に私もtcp_cls_cep()で失敗したことがあり、これが原因ではないかと考えてます。
config_tcpudp.c の設定項目で、_tcp_2msl変数があるのですが、これを"1"に変更して動作確認してみてもらえますか?
以下、理由です。
TCPはソケット毎に状態を持っています。LISTENINGとかESTABLISHEDとかCLOSEDとかです。
(コンピュータ上で動作するネットワークアプリのソケット毎の状態が、
コマンドプロンプトで netstat -aとやると見れるます)
そしてTCPの状態は以下のように遷移します。
http://www.atmarkit.co.jp/ait/articles/0402/13/news096_3.html
ソケットは、自分からFINを送る(CLOSEしようとする)とアクティブクローズと呼ばれる状態になり、
その中のTIME_WAIT状態で待ち状態に入ります。
このTIME_WAITでソケットは数分待ちます。(Windows等でも同じです)
Windows等のTCP/IPですとソケットを新しく作る度に動的にメモリを確保するため、
いくつかのソケットがTIME_WAIT状態であっても問題ないのですが、
ルネサスのTCP/IPの場合、コンパイル時にソケットの数が決まる方式でして、
なおかつ数個しかソケットを定義していない場合にアクティブクローズが大量に発生すると、
全てのソケットがTIME_WAITとなり、新しい接続が受け付けられない現象が発生します。
従ってこのTIME_WAITに留まる時間をconfig_tcpudp.cの_tcp_2mslの値を"1"に変更することで、
10msにしてしまえばすぐにソケットがCLOSED状態に戻り再利用可能になる、という算段です。
ちなみにTIME_WAIT状態にとどまる理由も以下に説明します。
直前のFIN_WAIT2からTIME_WAITに遷移し、
ACKの送信をしてすぐにCLOSEDに遷移すると、もしかすると、そのACKが消失してしまって、
通信相手はFINを再送してくるかもしれません。
このFINを受け取れるようにするために最大セグメント生存期間(Max Segment Lifetime)の
2倍を待ちましょう、というのがTCPのルールで決まっています。
ローカルエリアネットワークを使用したEthernet通信の場合、
ACKが消失することは稀であると考え、TIME_WAIT状態にとどまる時間を上記の通りに
短くしてしまっても特段問題が発生することはないと考えられます。
以上です。
以下についてもコメントします。
>> (ちなみにRI600使ってますが、通信端点ごとにタスクっているんでしょうか????)
リアルタイムOSを使用する場合、通信端点(=いわゆるソケットのこと)毎にタスクを割り当て、ブロッキングコールを使用すると良いです。
通信相手が複数居る場合、タスクを増やせば良い、といった考えですね。この場合アプリケーションをシンプルに記述出来ます。
リアルタイムOSを使用しない場合、ノンブロッキングコールを駆使して複数の通信端点を制御する
プログラムを作成すると良いです。この場合、アプリケーションは若干複雑になります。
ルネサスのFTPサーバはリアルタイムOSが無くても複数通信端点を扱えるように設計されているようで、
ノンブロッキングコールを駆使した作りになっています。
これをリアルタイムOS有りのシステムで動作させるためにはあまり考える必要なく、
R_ftpd()をメインタスク(または、空いている周期起動ハンドラ)でぐるぐる回せば動作すると思います。
以上です
シェルティさん、さんきゅーです。