Chapter4. 拡張関数


4.7 通信関数

関数名
P@SRVGETUSERIP
機能
サーバに接続してきたユーザのIPアドレスを取得する。
書式
P@SRVGETUSERIP(user)
《パラメーター》
user int。ユーザ番号を指定する
  
戻り値 指定したユーザ番号のIPアドレスを取得する。
取得に失敗した場合は−1を戻す。
解説
P@SRVMAKEで生成したポートに(P@USERMAKEを使って)接続してきたユーザのIPアドレスを数値で取得する。IPアドレスはネットワークにつながるすべてのパソコンに割り当てられる番号です。すべてのパソコンで異なる値が割り当てるので、住所のような役目を持ちます。そのため、技術的にはこの番号がわかればかなり正確に接続している人の情報を取得できます。(ただし、個人情報保護の観点から簡単に調べることはできません)
番号は1〜4294967295(4バイトの数値)の値になります。P@SRVGETUSERIP関数ではこの範囲の値を取得します。パソコンにとってはこの範囲の値でも問題ないのですが人に覚えつらいので、一般的には値を区切って記述します。この範囲は4バイトの数値で表現する値なのですが、1バイト(0〜255)毎に区切ります。
IPアドレスが「A.B.C.D」の場合は「(A*0x1000000)+(B*0x10000)+(C*0x100)+D」という計算式の結果を取得する。例えばユーザのIPアドレスが「192.168.0.1」の場合は3232235521を取得します。
逆にP@SRVGETUSERIP関数の結果を「A.B.C.D」形式の文字列に変化する場合には以下のようなプログラムで変換します。
  IP =P@SRVGETUSERIP(xxx)
  IP4 = IP % 256
  IP = IP / 256
  IP3= IP % 256
  IP = IP / 256
  IP2= IP % 256
  IP = IP / 256
  IP1= IP % 256
  g@printf(ch,0,0,str(IP1)+"."+str(IP2)+"."+str(IP3)+"."+str(IP4))
なお、あなたのパソコンに割り当てられた番号は「http://www.jppass.com/cgi/ip/ip.cgi」にアクセスすると知ることが出来ます。(例えば「218.110.225.64」というIPアドレスを取得します)
WindowsXPの「スタート」-「ファイル名を指定して実行」の選択で開いたダイアログに「cmd」と入力しOKをクリックします。するとcmd.exeが実行するので、「nslookup」と入力しEnterをクリックします。成功すると「>」という文字が表示されるので上で得たIPアドレス(例えば「218.110.225.64」)を入力しEnterをクリックすると「Name: p6ee140.ykhmac00.ap.so-net.ne.jp」というような結果を表示します。これがIPアドレスから調べることの出来る情報です。so-netの利用者であることがわかります。多分この結果をso-netに伝えれば利用者を特定できるはずです。
例えば、サーバで提供するサービスを悪意を持って攻撃を行う相手がいた場合は、このIPアドレスをキーにして攻撃する相手を特定し、攻撃をやめさせたり、攻撃を回避する措置をとることができます。
ただし、プロバイダのサービスを利用している場合には、割り当てるIPアドレスが変わることがあります。その為、IPアドレスだけで接続制限を行うと次にそのIPアドレスを割り当てられた人が接続できなくなるので問題になるかもしれません。一時的に制限するという使い方がいいかもしれません。
少し高度な使い方になりますが日本に割り当てられているIPアドレスは「http://www.apnic.net/apnic-bin/ipv4-by-country.pl?country=JP」で調べることが出来るので、海外からのIPアドレスを範囲で制限する手法は有効です。
用例
ユーザがサーバに接続するとサーバからメッセージが送られる。そして直ぐに切断される。サーバアプリを実行後、クライアントを実行する。クライアントは複数実行できる。
//サーバ
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                    //接続した?
    IP =P@SRVGETUSERIP(UU)
    IP4= IP % 256
    IP = IP / 256
    IP3= IP % 256
    IP = IP / 256
    IP2= IP % 256
    IP = IP / 256
    IP1= IP % 256
    MOJI$=STR(IP1)+"."+STR(IP2)+"."+STR(IP3)+"."+STR(IP4)+"が接続してきました"
    P@PUSHSTR(UU,"やっほー")         //送信メッセージ登録
    P@SEND(UU)                       //送信
    P@CLOSE( UU )                    //クライアント切断
  ELSE
    MOJI$="接続待ち"
  ENDIF
  G@PRINT(CH,0, 0,MOJI$)
  G@FLIP()                           //画面更新
  S@SLEEP(1000)
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