ページ 11

uNet3ソケットAPIのノンブロッキングモードによる送受信方法

Posted: 2018年7月13日(金) 08:38
by osaka-tc
お世話になります。

プラットフォームは、Renesas R-IN32M3-EC(ITRON使用)です。
産業イーサネット関連の機器を開発しています。
uNet3ソケットAPIのノンブロッキングモードによる送受信操作で独自のHTTPサーバを組み込もうとしています。
Renesas殿から提供されるTCP/IPマニュアルでは、ノンブロッキングモードによける各APIの詳細な動きに関する説明が不十分で、手さぐりでプログラミング中です。
そこで、メーカである御社に、uNet3のノンブロッキングモード・プログラミングに関する参考となる資料がないか問い合わせをさせていただくことにいたしました。
評価版等に正式版の製品マニュアルも付属していたりするでしょか?

Renesas殿にライセンス供与されている製品かと思いますので、いろいろとお手数をおかけすることについて恐縮するところですが、今後、他のプラットフォームでもuNet3を活用する場面もでてくる可能性もありますので、しっかりとAPIをつかったプログラミングを押さえておきたいと考えています。

宜しくお願いいたします。

Re: uNet3ソケットAPIのノンブロッキングモードによる送受信方法

Posted: 2018年7月18日(水) 15:33
by eForce技術担当
弊社ホームページよりダウンロードして頂ける評価版にuNet3のマニュアルも付属しており、ノンブロッキングモードについての記載もございますが、内容としてはRenesas殿のTCP/IPマニュアルと同等となりますので、さらに詳細な説明ということではございません。現在のところその他の説明資料のご用意はございませんが、参考までにノンブロッキングモードでの各ソケットAPIの動作や注意点などについて、以下に記載致します。マニュアルと合わせてご参照ください。

●ノンブロッキングモード動作の流れ
ノンブロッキングモードを使用するには、ソケットのパラメータ設定用API(cfg_soc)を使用してあらかじめソケットに対してコールバック関数を登録し、ノンブロッキングモードに設定する対象のソケットAPI(con_soc/cls_soc/snd_soc/rcv_soc)を指定します。
ノンブロッキングモードに設定した状態で各ソケットAPIを呼び出した場合、APIの戻り値がE_WBLKである場合(ノンブロッキングモードで処理したことを示す)に限り、コールバックされます。
E_WBLK以外のエラーコード返却時や待ち要因がなく正常終了した場合はコールバックされません。

●ノンブロッキングモード動作となる待ち要因
各API呼出し時に待ち要因がある場合にノンブロッキングモードで処理され、E_WBLKが返されます。
各APIでE_WBLKが返される主な待ち要因は下記の通りです。

1)TCPソケット
 ・con_soc(ソケットの接続)
  con_flg=SOC_CLIの場合(クライアント):サーバからのSYN/ACK待ち
  con_flg=SOC_SERの場合(サーバー):クライアントからのSYN待ち

 ・cls_soc(ソケットの切断)
  cls_flg=SOC_TCP_CLSの場合(接続を終了):FINに対するACKおよび対向からのFIN待ち
  cls_flg=SOC_TCP_SHTの場合(送信のみ無効):待ち要因なし

 ・rcv_soc(データの受信)
  データ受信待ち

 ・snd_soc(データの送信)
  送信バッファの空き待ち

2)UDPソケット
 ・con_soc(ソケットの接続)
  待ち要因なし

 ・cls_soc(ソケットの切断)
  待ち要因なし

 ・rcv_soc(データの受信)
  データ受信待ち

 ・snd_soc(データの送信)
  アドレス解決、ドライバの送信完了待ち

●ノンブロッキングモード使用時の注意点
1) ノンブロッキングモードに設定した場合でも、必ずコールバック関数が呼び出されるのではなく、各ソケットAPIの戻り値がE_WBLKの場合のみコールバック関数が呼び出されます。
従って通常は各ソケットAPI呼び出し時に戻り値に応じた制御が必要になります。

2) コールバック関数はTCP/IPまたはドライバのコンテキストで実行されますので、コールバック関数からソケットAPIの呼び出しや待ち状態に入る制御は行わないでください。

3) コールバック待ち中の多重呼び出しは受付できません。ソケットAPI呼び出し後、コールバック前に同一ソケットに対して同一APIを呼び出すと戻り値にE_QOVRが返ります。

Re: uNet3ソケットAPIのノンブロッキングモードによる送受信方法

Posted: 2018年7月20日(金) 10:24
by osaka-tc
eForce技術担当様

Replyありがとうございます。
大変丁寧な回答で参考になります。

ちょうど今、弊社オリジナル機器へ専用組み込みWEBサーバを実装しているところですが、
ノンブロッキングモードでのsnd_soc() APIで、送信した場合のuNet3 TCP/IPスタックから送出されて
くる送信データについてご教授ください。

HTTPプロトコルによるWEB応答ページを送信した場合についてです。
2kByte以上のWEBページを送信しようとしています。
snd_soc() APIで送信した場合、EthernetのMTUサイズ(1500)制約(正確には、TCPパケットWindowsサイズ)
を受けて、スタックからTCPフレームが分割出力されてきます。
このとき分割されたのTCPヘッダのフラグには、それぞれにPSH/ACKが付いています。
ちょっとわからないのが、分割2フレーム目出力前に、TCPデータサイズ0のRST/ACKフラグ
付きフレームが必ず出力されてくるのですがなぜでしょうか?
このタイミングでRST/ACK TCPスレームが挿入される考えられる理由をご教示いただけないでしょうか?

クライアント側からのRSTを受けた?ためと考える必要があるでしょうか?
その場合は、アプリケーション側で適切なCLOSE処理が必要等があるでしょうか?

すみませんが、宜しくお願いします。

Re: uNet3ソケットAPIのノンブロッキングモードによる送受信方法

Posted: 2018年7月20日(金) 10:52
by osaka-tc
すみません、状況補足します。

現在のWEBサーバ動作の作りは、クライアントからのGET/PUT等リクエスト毎に、
応答送信したのち接続を一旦切断(abt_soc() API)し、その後再接続(con_soc() API)
し直してから次のリクエストを待つという内容となっています。
(現状、簡易WEBサーバ的な機能と位置付けて、擬似的に複数のクライアントからの
リクエストに応答するような作りとしています。)

現象に対して、関係がありそうなので補足しました。
宜しくお願いします。

Re: uNet3ソケットAPIのノンブロッキングモードによる送受信方法

Posted: 2018年7月27日(金) 13:54
by eForce技術担当
μNet3のTCPスタックからRSTを送信する契機について、よくある質問のページにまとめて記載しました。
参考にして頂ければと思います。

掲示板トップ ‹ eForceからのお知らせ ‹ よくあるご質問(技術) ‹ μNet3 

Re: uNet3ソケットAPIのノンブロッキングモードによる送受信方法

Posted: 2018年8月01日(水) 15:28
by osaka-tc
回答ありがとうございます。

RST送信のきっかけ理解しました。

関連しますが、
rcv_soc / snd_soc 各API のノンブロッキングモード時の戻り値が「0」の場合の意味をご教示ください。
rcv_soc APIの場合は、API呼び出し後に「FIN」受信した場合に「0」が返却されるようですが、snd_soc APIの場合も同様でしょうか?
マニュアルには、「<=0」(0を含んでそれ以下)の場合は、API処理のエラーでエラーコード表を参照と記載されています。
TCPソケットを使用しています。

宜しくお願いいたします。

Re: uNet3ソケットAPIのノンブロッキングモードによる送受信方法

Posted: 2018年8月21日(火) 16:17
by eForce技術担当
rcv_soc についてはご認識の通りです。
snd_soc に関しては、FIN受信に関わらずアプリケーションからcls_socを呼び出すまでは送信処理は継続されますので、FIN受信がsnd_socのコールバック契機とはなりません。
マニュアルでsnd_soc のコールバックによる戻り値は0以下をエラーと記載していますが、0に特定の意味を持たせていません。

Re: uNet3ソケットAPIのノンブロッキングモードによる送受信方法

Posted: 2018年10月12日(金) 10:45
by osaka-tc
回答ありがとうございました。

ノンブロッキングモードによるTCP送受信について、今少し質問させてください。
ノンブロッキングモードで送信後にソケットをクローズする場合、クローズ前の送信完了をどのように判断すればよいでしょうか?
ノンブロッキングsnd_soc送信の戻り値は、0以上でバッファ空きバイト数が返却されることになっており、返却空きバイト数の管理により予定送信データバイト数と一致した時点で送信完了と判断して、すぐにクロースcls_socしても大丈夫でしょうか?
送信レディ(?)を確認してからクローズする必要があるように思うのですが、この場合の処置のあるべき方法をご教示いただけないでしょうか。

宜しくお願いいたします。