前提
Norti ver.4(μITRON系RTOS)を使って組込み制御プログラムを作っています。
Nortiにはミスポ製のTCP/IPプロトコルスタックが含まれているため、
今回はそれを用いてTCP通信を行います。
実現したいこと
今回作成するプログラムはTCPのサーバ側(リッスンする側)なので、
プログラム起動したらソケット(Nortiでは「通信端点」と呼ぶ)を作成し、
プロトコルスタックのAPI、tcp_acp_cep()を呼び出して当該通信端点のリッスンを開始します。
通信相手(クライアント側)からSYNが送信されてきたらプロトコルスタック内で自動的に3wayハンドシェイクが実施されてTCPコネクションがなされ、データの送受信を行います。
データ送受信が終了し、相手側からFINやRSTが送信されてきたら(もしくは回線が物理断したら)通信端点を閉じて、
次の接続に備えて再度tcp_acp_cep()を呼び出してリッスンに戻りたいです。
わからないこと
NortiのTCP/IPプロトコルスタックは、様々なイベントを通信端点に紐付けたコールバックルーチンで教えてくれて重宝しているのですが、
プロトコルスタックのマニュアルを熟読しても
「通信相手からFINやRSTが送信されてきて、TCP接続を切断したこと」「回線が物理的に切れてしまいTCP接続を切断したこと」
をコールバックで知る手段の記述が無く、どう設計すればいいか困っています。
※自分から切断しに行った場合(API・tcp_cls_cep()を呼び出した場合)の切断完了をコールバックで教えてくれる旨は記載があるのですが、相手から一方的に切られたことを知る方法の記載が見つかりません。
相手から接続が切断されたことを知ることが出来ないと、tcp_acp_cep()を呼び出してのリッスン再開が出来ず、通信端点が1回きり使いすてになってしまいます。
TCP接続が切断されたことを受動的に知るにはどうすればよいのでしょうか?
該当のソースコード
ざっくりサンプルコードを書いてみました。
今回はC言語で開発しています。
(エラーハンドリングなどは省略しています)
C言語
1/* 2 * コールバックからの受け渡し情報用グローバル変数 3 */ 4ID rcvCep; /* 受信CEP格納用 */ 5FN rcvFnCd; /* 受信機能コード格納用 */ 6 7/* 8 受信する機能コードの種類はマニュアルによると以下の通り 9 10 TFN_TCP_ACP_CEP (-0x205) tcp_acp_cep 完了通知 11 TFN_TCP_CON_CEP (-0x206) tcp_con_cep 完了通知 12 TFN_TCP_CLS_CEP (-0x208) tcp_cls_cep 完了通知 13 TFN_TCP_SND_DAT (-0x209) tcp_snd_dat 完了通知 14 TFN_TCP_RCV_DAT (-0x20a) tcp_rcv_dat 完了通知 15 TFN_TCP_GET_BUF (-0x20b) tcp_get_buf 完了通知 16 TFN_TCP_RCV_BUF (-0x20d) tcp_rcv_buf 完了通知 17 TFN_UDP_SND_DAT (-0x223) udp_snd_dat 完了通知 18 TFN_UDP_RCV_DAT (-0x224) udp_rcv_dat 完了通知 19 */ 20 21 22/* 23 * メインルーチン 24 */ 25int mainRoutine(){ 26 T_TCP_CREP pk_crep; /* TCP受付口生成情報 */ 27 ID repid; /* TCP受付口ID */ 28 T_TCP_CCEP pk_ccep; /* TCP通信端点生成情報パケット */ 29 ID cepId; /* TCP通信端点ID */ 30 T_IPV4EP distAddr; /* 接続受付アドレス情報 */ 31 TMO tmout; /* タイムアウト指定 */ 32 33 // 34 //~~~このあたりに変数の初期化処理~~~ 35 // 36 37 /* TCP受付口生成呼び出し*/ 38 tcp_cre_rep(repid, &pk_crep); 39 40 /* TCP通信端点生成のシステムコール呼び出し */ 41 tcp_cre_cep(cepId, &pk_ccep); 42 43 /* リッスン開始 */ 44 tcp_acp_cep(cepId, repid, &distAddr, tmout); 45 46 // メインループ 47 while(1){ 48 49 //コールバックからのイベント通知を待つ(コールバック発生までここでブロッキングのイメージ) 50 waitMsg(); 51 52 /* サービスコールの機能コードに応じて分岐 */ 53 switch(rcvFnCd) 54 { 55 //クローズ完了 56 case TFN_TCP_CLS_CEP: 57 //クローズ完了したら再度リッスン開始 58 tcp_acp_cep(cepId, repid, &distAddr, tmout); 59 break; 60 61 //送信完了 62 case TFN_TCP_SND_DAT: 63 //送信完了時の処理省略 64 break; 65 66 //受信完了 67 case TFN_TCP_RCV_DAT: 68 //受信完了時の処理省略 69 break; 70 71 // 72 //~~~ このあたりでcaseの一つとして、相手からのコネクション切断を判断できないか?~~~ 73 // 74 75 default: 76 break; 77 } 78 } 79 80 return 0; 81} 82 83 84/* 85 * Nortiからのコールバック関数 86 */ 87void callback(ID cepId, FN fnCd, VP parblk) 88{ 89 /* 受信CEPをセット */ 90 rcvCep = cepId; 91 92 /* 機能コードを格納 */ 93 rcvFnCd = fnCd; 94 95 /* イベント発生をmainRoutineに通知 */ 96 sendMsg(); 97 98 return; 99} 100
補足情報
OS:Norti ver4
・NortiTCP/IPプロトコルスタックのマニュアルPDF
http://www.mispo.co.jp/document/n4nguid.pdf

回答1件
あなたの回答
tips
プレビュー