Chapter4. 拡張関数


4.7 通信関数

関数名
P@SEND
機能
データを送信する
書式
int P@SEND( user/server )
《パラメーター》
user/server int。ユーザ番号またはサーバ番号を指定する
  
戻り値 −1:通信エラー
0:送信待ち
1以上:送信完了。戻り値は実際の送信データ長
解説
送信したいデータはP@PUSHINTおよびP@PUSHSTRで一旦バッファに溜め、P@SENDでまとめて送信する。受信はP@RECVでおこなう。
1回の送受信にはかなりの時間(小さいデータでも0.1秒以上かかることもある)が必要となるため、できるだけ多くのデータをまとめて送るべきである。
1回に送ることのできるデータ長は32768バイトです。数字は1つで4バイト、文字列は固定で5バイトに加え半角1文字で1バイト、全角1文字で2バイトを消費する。
通信障害ではないが送信に失敗した場合に0が戻る。理由には「接続処理中である」「前回送信したデータを通信相手が処理し切れていないため次を送信できない」などがある。前者の場合はP@USERGETSTATEで接続の完了を確認した後に再度送信を行う。後者の場合は時間を置いてから再度送信を行う。P@SENDは成功するまで登録したバッファは削除されないので、P@SENDに失敗した後の再送信ではデータの登録を再度行う必要はない。
用例
ユーザがサーバに接続するとサーバからメッセージが送られる。そして直ぐに切断される。サーバアプリを実行後、クライアントを実行する。クライアントは複数実行できる。
//サーバ
S@BACKGROUND( 2 )                    //非アクティブでも動かす
CH = G@SETUP(300,200,16,1)           //画面初期化
SV = P@SRVMAKE( 5000 )               //サーバ通信開始
LOOP
  G@CHRCLEAR( CH )                   //画面クリア
  UU = P@SRVGETUSER( SV )            //クライアント接続チェック
  IF UU <> 0 THEN                    //接続した?
    MOJI$="接続してきました"
    P@PUSHSTR(UU,"やっほー")         //送信メッセージ登録
    P@SEND(UU)                       //送信
    P@CLOSE( UU )                    //クライアント切断
  ELSE
    MOJI$="接続待ち"
  ENDIF
  G@PRINT(CH,0, 0,MOJI$)
  G@FLIP()                           //画面更新
  S@SLEEP(500)
ENDLOOP
 
//クライアント
S@BACKGROUND( 2 )                    //非アクティブでも動かす
CH = G@SETUP(300,200,16,1)           //画面初期化
SV = P@USERMAKE("127.0.0.1" , 5000)  //サーバに接続開始
RMODE=0
LOOP
  G@CHRCLEAR( CH )                   //画面クリア
  IF SV <> 0 THEN                    //接続待ち or 接続中
    PRET = P@USERGETSTATE( SV )      //接続状態チェック
    SELECT
    WHEN PRET=0:                     //接続中?
      MOJI$="接続中…"
      BREAK
    WHEN PRET=1:                     //接続完了?
      MOJI$="接続しました"
      RMODE=1                        //受信可能とする
      BREAK
    WHEN PRET=-1:                    //接続失敗?
      MOJI$="接続失敗"
      SV = 0
      BREAK
    ENDSELECT
    IF RMODE = 1 THEN                //受信可能?
      IF 0 < P@RECV(SV) THEN         //受信 and 受信した?
        MOJI2$=P@POPSTR(SV)          //受信文字列取得
        P@CLOSE(SV)                  //サーバと切断
        SV=0
      ENDIF
    ENDIF
  ENDIF
  G@PRINT(CH,0, 0,MOJI$)
  G@PRINT(CH,0,20,MOJI2$)
  G@FLIP()                           //画面更新
ENDLOOP