#!/usr/local/bin/tt

# 簡易 TCP モニター（サーバー）です。指定された｛IPアドレスorホスト名｝＆｛ポート番号orサービス名｝にて、
# TCP クライアントからの接続を待ち受け、接続要求を処理し（リンクを確立し）、その後、
# TCP クライアントからのメッセージを待ち受け受信し、その接続での受信データーを表示します。

/*--1---2---3---4---5---6---7---8---9---A---B---C---D---E---F---G---H---I---J---K---L---M---N---*/
# 引数の確認
global option = opshift()
if( argr!=2 )
    dying("使い方:  %s  [-v]  (Server)IPアドレスorホスト名  (Server)ポート番号orサービス名\n",CMD)

# サーバー情報の取得
ip   = shift()                          # IPアドレス、又は、ホスト名  （文字列）
port = shift()                          # ポート番号、又は、サービス名（文字列）

# サーバー用 TCP ソケットの作成
sock = tcp_socket(ip,port);
if( sock==NULL )
    dying("TCP %s<Server>%s Error: cannot make TCP socket!!\n",C_BLU,C_DEF)
disp_sockbase(sock)                     # 作成直後のソケット情報

while(TRUE){

    # ソケット sock で接続の待ち受けをし、ソケット work で受信をする
    work = listen(sock)

    # Listen & Accept の表示
    print("TCP %s<Server>%s %sListen Socket = %d / Return Socket = %d%s\n",C_BLU,C_DEF,C_YEL,sock,work,C_DEF);
    disp_sockbase(sock)                     # 接続直後のソケット情報
    disp_sockwork(work)                     # 接続直後のソケット情報

    # 受信（デフォルトソケット TCP_SOCKET{=work} を利用）
    while(TRUE){
        (msg,len) = rx_tcp()
	    if(msg==NULL||len==NULL)
		    break
        print("TCP %s<Server>%s %sRecv From:%s Message=\"%s\"(Length=%d)\n",C_BLU,C_DEF,C_GRE,C_DEF,msg,len)
        disp_sockbase(sock)                 # 受信直後のソケット情報
        disp_sockwork(work)                 # 受信直後のソケット情報
    }

}

# ソケット情報を、初回時及び変化時のみ表示する。（オプション "-v" 指定時は常に表示）
/*--1---2---3---4---5---6---7---8---9---A---B---C---D---E---F---G---H---I---J---K---L---M---N---*/
def disp_sockbase(sock){

static flag_init=TRUE
static lo_ip,lo_port,lo_type,ro_ip,ro_port,ro_type

    # ソケット情報の読み込み
    (lx_ip,lx_port,lx_type,rx_ip,rx_port,rx_type) = sockinfo(sock)

    # 変化の検出
    if( flag_init || lo_ip!=lx_ip || lo_port!=lx_port || lo_type!=lx_type \
                  || ro_ip!=rx_ip || ro_port!=rx_port || ro_type!=rx_type )
        flag_diff=TRUE
    else
        flag_diff=FALS

    # 表示＆FIFO
    if( option=="-v" || flag_diff ){
        flag_init=FALS
        lo_ip=lx_ip; lo_port=lx_port ; lo_type=lx_type
        ro_ip=rx_ip; ro_port=rx_port ; ro_type=rx_type
        print("TCP ${C_BLU}<Server>${C_YEL} Sock=%d ",sock)
        print("[Loc]IP=%s/Port=%5s/Type=%s "         ,lo_ip==NULL?"(null)":ip2str(lo_ip),str(lo_port),str(lo_type))
        print("[Rem]IP=%s/Port=%5s/Type=%s${C_DEF}\n",ro_ip==NULL?"(null)":ip2str(ro_ip),str(ro_port),str(ro_type));
    }

}

# ソケット情報を、初回時及び変化時のみ表示する。（オプション "-v" 指定時は常に表示）
/*--1---2---3---4---5---6---7---8---9---A---B---C---D---E---F---G---H---I---J---K---L---M---N---*/
def disp_sockwork(sock){

static flag_init=TRUE
static lo_ip,lo_port,lo_type,ro_ip,ro_port,ro_type

    # ソケット情報の読み込み
    (lx_ip,lx_port,lx_type,rx_ip,rx_port,rx_type) = sockinfo(sock)

    # 変化の検出
    if( flag_init || lo_ip!=lx_ip || lo_port!=lx_port || lo_type!=lx_type \
                  || ro_ip!=rx_ip || ro_port!=rx_port || ro_type!=rx_type )
        flag_diff=TRUE
    else
        flag_diff=FALS

    # 表示＆FIFO
    if( option=="-v" || flag_diff ){
        flag_init=FALS
        lo_ip=lx_ip; lo_port=lx_port ; lo_type=lx_type
        ro_ip=rx_ip; ro_port=rx_port ; ro_type=rx_type
        print("TCP ${C_BLU}<Server>${C_YEL} Sock=%d ",sock)
        print("[Loc]IP=%s/Port=%5s/Type=%s "         ,lo_ip==NULL?"(null)":ip2str(lo_ip),str(lo_port),str(lo_type))
        print("[Rem]IP=%s/Port=%5s/Type=%s${C_DEF}\n",ro_ip==NULL?"(null)":ip2str(ro_ip),str(ro_port),str(ro_type));
    }

}
