IBM i でクライアントとソケット通信でテータ送受信する仕組みを構築したお客様で、クライアント側の操作がおかしい場合や誤操作した際などにIBM i 側とのソケットコネクションを設定したインターバル時間経過後にIBM i 側から遮断(リセット)したい、というご相談です。
上手くいかなかった例
・ILE RPGでSOCKET()でソケットを作成
・LISTEN()で待ち受け → ACCEPT()でクライアントから接続
・通常は、RECV()でクライアントからのデータを受信
・この時、クライアント側の誤操作その他が発生した際に、あらかじめ決めた秒数経過後に、RECV()処理をタイムアウトにしたい。
ご相談いただいた時点では、タイムアウトが設定できずクライアントからの異常なリクエストの通信がスタックして滞留するケースが発生していました。
最初のトライ(失敗したケース)
ソケット作成後にSETSOCKOPT()のオプション名にSO_RCVTIMEOを指定してタイムアウト時間を指定する方法をトライしましたが、
SETSOCKOPT()でタイムアウトを設定するサンプルが分からず、、という事でした。
例えばこの辺の記事などを参考にしてプログラミングしたとの事
setsockopt()--Set Socket Options
https://www.ibm.com/docs/ja/i/7.5?topic=ssw_ibm_i_75/apis/ssocko.html
上記のソケットタイムアウト値の設定などの情報があまり見つからないようです・・
別なトライ(成功ケース)
結局SETSOCKOPTはあきらめて、別なプログラミングにトライしたところ期待通りの動作が実現できたとのことでした。大まかには下記になります。
①SOCKET()でソケットを作成
②LISTEN()でクライアント要求を待機
③ACCEPT()でクライアントの接続要求を許可
④SELECT()でタイムアウトの秒数を設定
⑤ソケットが読み取り可能か確認
⑥ソケットが読み取り可能な場合以下実行
⑦ソケットから読み取りできず指定秒数でタイムアウトした場合、接続をクローズして①に戻る。
⑧RECV()でクライアントからのデータを読取り
⑨SEND()でクライアントへデータ送信
⑩接続を閉じて初期化し②に戻る
K様ありがとうございました自身大変勉強になりましたm(_ _)m