星期二, 11月 07, 2023

2007-06-27 如何判斷系統上某一 IP 位址是否已啟動? (CHKTCPIFC with API QtocRtvTCPA, QtocLstNetIfc)


如何判斷系統上某一 IP 位址是否已啟動? (CHKTCPIFC with API QtocRtvTCPA, QtocLstNetIfc)

如何判斷系統上某一 IP 位址是否已啟動? (CHKTCPIFC with API QtocRtvTCPA, QtocLstNetIfc)
由於我們時常使用 TCP/IP Socket 程式, 要讓程式自動於開機時啟動, 我們大多會將程式置於系統的開機
啟動程式(指定於系統值 QSTRUPPGM)中 , 有時候系統於開機過程中啟動 TCP/IP 介面會比我們所設定的開
機啟動程式慢,此時若於啟動程式中直接啟動 Socket 程式, 會導致該 Socket 程式由於該 Interface 位址
未啟動而造成某些錯誤,所以於執行 TCP/IP Socket 程式前就要判斷該 Interface 位址是否已啟動, 如此
方式可以使 TCP/IP Scoket 程式較容易撰寫重試(retry)過程.所以 Command CHKTCPIFC 就是來確認所指
定的 Interface 位址是否已啟動, 


File  : QCLSRC
Member: CHKTCPIFC
Type  : CLLE
Usage : CRTBNDCL CHKTGTRLSC
OS version: V5R1 以後(含)        


/*  ===============================================================  */
/*  = Command ChkTcpIfc  CPP                                      =  */
/*  =   ChkTcpIfc  CLLE                                           =  */
/*  =   Paramater notes:                                          =  */
/*  =     NetIfc   :Network interface address                     =  */
/*  =                                                             =  */
/*  = For V5R1 and later use                                      =  */
/*  =                                                             =  */
/*  = Usage in CLP:                                               =  */
/*  =   ChkTcpIfc NETIFC( ip_address )                            =  */
/*  =   MONMSG CPF9898 => Possible error as following:            =  */
/*  =                     1. TCP/IP is not active.                =  */
/*  =                     2. Interface address is not active.     =  */
/*  =                     3. Interface address is not defined.    =  */
/*  ===============================================================  */
/*  = Date  : 2007/06/26                                          =  */
/*  = Author: Vengoal Chang                                       =  */
/*  ===============================================================  */

PGM  (&NetIfc)

             DCL        VAR(&NETIFC) TYPE(*CHAR) LEN(15)
             DCL        VAR(&RCVVAR) TYPE(*CHAR) LEN(140)
             DCL        VAR(&APIERR) TYPE(*CHAR) LEN(8) +
                          VALUE(X'0000000000000000')
             DCL        VAR(&TCPAFORMAT) TYPE(*CHAR) LEN(8) +
                          VALUE('TCPA0100')
             DCL        VAR(&NIFCFORMAT) TYPE(*CHAR) LEN(8) +
                          VALUE('NIFC0100')
             DCL        VAR(&RCVVARLEN) TYPE(*CHAR) LEN(4)
             DCL        VAR(&TCPSTKSTS) TYPE(*CHAR) LEN(4)
             DCL        VAR(&TCPSTKSTSN) TYPE(*DEC) LEN(10) VALUE(0)

             DCL        VAR(&USP_NAME) TYPE(*CHAR) LEN(10)
             DCL        VAR(&USP_LIB)    TYPE(*CHAR) LEN(10)
             DCL        VAR(&USP_QUAL)   TYPE(*CHAR) LEN(20)
             DCL        VAR(&USP_TYPE)   TYPE(*CHAR) LEN(10)
             DCL        VAR(&USP_SIZE)   TYPE(*CHAR) LEN(4)
             DCL        VAR(&USP_FILL)   TYPE(*CHAR) LEN(1)
             DCL        VAR(&USP_AUT)    TYPE(*CHAR) LEN(10)
             DCL        VAR(&USP_TEXT)   TYPE(*CHAR) LEN(50)
             DCL        VAR(&STARTPOS)   TYPE(*CHAR) LEN(4)
             DCL        VAR(&DATALEN)    TYPE(*CHAR) LEN(4)
             DCL        VAR(&HEADER)     TYPE(*CHAR) LEN(150)
             DCL        VAR(&LST_OFFSET) TYPE(*DEC)  LEN(5 0)
             DCL        VAR(&LST_SIZE)   TYPE(*DEC)  LEN(5 0)
             DCL        VAR(&LST_DATA)   TYPE(*CHAR) LEN(4096)
             DCL        VAR(&LST_NBR)    TYPE(*DEC)  LEN(5 0)
             DCL        VAR(&LST_LEN)    TYPE(*DEC)  LEN(5 0)
             DCL        VAR(&LST_LENBIN) TYPE(*CHAR) LEN(4)
             DCL        VAR(&LST_POSBIN) TYPE(*CHAR) LEN(4)
             DCL        VAR(&LST_COUNT)  TYPE(*DEC)  LEN(5) VALUE(0)
             DCL        VAR(&EXC_COUNT)  TYPE(*DEC)  LEN(5) VALUE(0)

             DCL        VAR(&INTNETADR)  TYPE(*CHAR) LEN(15)
             DCL        VAR(&NETWORKADR) TYPE(*CHAR) LEN(15)
             DCL        VAR(&HOSTADR)    TYPE(*CHAR) LEN(15)
             DCL        VAR(&IFCSTSN)    TYPE(*DEC)  LEN(5) VALUE(0)
             DCL        VAR(&IFCSTSC)    TYPE(*CHAR) LEN(5)
             DCL        VAR(&NULL) TYPE(*CHAR) LEN(1) VALUE(X'00')
             DCL        VAR(&idx ) TYPE(*dec ) LEN(5) VALUE(0)
             DCL        VAR(&NETIFCDFN) TYPE(*CHAR) LEN(1)

             DCL        VAR(&MSGID) TYPE(*CHAR) LEN(7)
             DCL        VAR(&MSGDTA) TYPE(*CHAR) LEN(256)
             DCL        VAR(&MSGF) TYPE(*CHAR) LEN(10)
             DCL        VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)
             DCL        VAR(&MSGTXT) TYPE(*CHAR) LEN(256)

             MONMSG     MSGID(CPF0000 MCH0000) EXEC(GOTO CMDLBL(ERROR))

             chgvar %Bin(&RcvVarLen) 140
             callprc 'QtocRtvTCPA' ( +
                                    &RcvVar    +
                                    &RcvVarLen +
                                    &TCPAFormat    +
                                    &ApiErr)

             ChgVar  &TcpStkSts     %SST(&RcvVar 9 4)
             ChgVar  &TcpStkStsn    %bin(&TcpStkSts)

             IF      (&TCPStkStsn *EQ 0) DO
               SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('TCP/IP +
                          status is not active.') MSGTYPE(*ESCAPE)
             ENDDO

             CHGVAR     VAR(&USP_NAME) VALUE('CHKTCPIFC' )
             CHGVAR     VAR(&USP_LIB)  VALUE('QTEMP')
             CHGVAR     VAR(&USP_QUAL) VALUE(&USP_NAME *CAT +
                          &USP_LIB)
             CHGVAR     VAR(&USP_TYPE) VALUE('MYTYPE')
             CHGVAR     VAR(%BIN(&USP_SIZE)) VALUE(65535)
             CHGVAR     VAR(&USP_FILL) VALUE(' ')
             CHGVAR     VAR(&USP_AUT)  VALUE('*CHANGE')
             CHGVAR     VAR(&USP_TEXT) VALUE('my user space')

             DLTUSRSPC  USRSPC(&USP_LIB/&USP_NAME)
             MONMSG CPF0000

             CALL       PGM(QUSCRTUS) PARM(&USP_QUAL &USP_TYPE +
                          &USP_SIZE &USP_FILL &USP_AUT &USP_TEXT)

             ChgVar  &ApiErr X'0000000000000000'
             callprc 'QtocLstNetIfc' ( +
                                      &USP_QUAL  +
                                      &NIFCFormat    +
                                      &ApiErr)

             CHGVAR     VAR(%BIN(&STARTPOS)) VALUE(1)
             CHGVAR     VAR(%BIN(&DATALEN))  VALUE(140)

             CALL       PGM(QUSRTVUS) PARM(&USP_QUAL &STARTPOS +
                          &DATALEN &HEADER)

             CHGVAR     VAR(&LST_OFFSET) VALUE(%BIN(&HEADER 125 4))
             CHGVAR     VAR(&LST_SIZE)   VALUE(%BIN(&HEADER 129 4))
             CHGVAR     VAR(&LST_NBR)    VALUE(%BIN(&HEADER 133 4))
             CHGVAR     VAR(&LST_LEN)    VALUE(%BIN(&HEADER 137 4))

             CHGVAR     VAR(%BIN(&LST_POSBIN)) VALUE(&LST_OFFSET + 1)
             CHGVAR     VAR(&LST_LENBIN) VALUE(%SST(&HEADER 137 4))

             CHGVAR     VAR(&LST_COUNT) VALUE(0)
             CHGVAR     VAR(&EXC_COUNT) VALUE(0)


 LST_LOOP:   IF         COND(&LST_COUNT *EQ &LST_NBR) THEN(GOTO +
                          CMDLBL(LST_END))

             CALL       PGM(QUSRTVUS) PARM(&USP_QUAL &LST_POSBIN +
                          &LST_LENBIN &LST_DATA)

             CHGVAR     VAR(&INTNETADR)  VALUE(%SST(&LST_DATA  1 15))
   /*        CHGVAR     VAR(&NETWORKADR) VALUE(%SST(&LST_DATA 21 15))*/
   /*        CHGVAR     VAR(&HOSTADR   ) VALUE(%SST(&LST_DATA 89 15))*/
             CHGVAR     VAR(&IFCSTSN)    VALUE(%BIN(&LST_DATA 73 4))
             CHGVAR     VAR(&IFCSTSC)    VALUE(&IFCSTSN)

             ChgVar     &Idx 1
 CVTNULLS:
             If (&Idx > 15) goto CVTNULLE
             If (%SST(&INTNETADR &Idx 1) *EQ &null) +
                ChgVar %SST(&INTNETADR &Idx 1) ' '

             ChgVar     &Idx (&Idx+1)
             goto CVTNULLS
 CVTNULLE:

             If (&NETIFC *EQ &INTNETADR) DO
               ChgVar &NETIFCDFN '1'
               If  (&IFCSTSN *EQ 1) DO
                  SNDPGMMSG  MSGID(CPF9897) MSGF(QCPFMSG) +
                             MSGDTA('Interface' *BCAT &NETIFC *BCAT +
                                    'is active.') MSGTYPE(*INFO)
                  CHGVAR     VAR(&EXC_COUNT) VALUE(&EXC_COUNT + 1)
                  GOTO LST_END
               ENDDO

             ENDDO

             CHGVAR     VAR(&LST_COUNT) VALUE(&LST_COUNT + 1)
             CHGVAR     VAR(%BIN(&LST_POSBIN)) +
                          VALUE(%BIN(&LST_POSBIN) + &LST_LEN)
             GOTO       CMDLBL(LST_LOOP)

 LST_END:
             IF (&EXC_COUNT *EQ 0) DO
             If (&NetIfcDfn *EQ '1') +
             SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) +
                          MSGDTA('Interface' *BCAT +
                                 &NETIFC *BCAT 'is not active') +
                          MSGTYPE(*ESCAPE)
             Else +
             SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) +
                          MSGDTA('Interface' *BCAT +
                                 &NETIFC *BCAT 'is not defined') +
                          MSGTYPE(*ESCAPE)
             ENDDO

             DLTUSRSPC  USRSPC(&USP_LIB/&USP_NAME)

   Return

/*  ===============================================================  */
/*  = Error routine                                               =  */
/*  ===============================================================  */

Error:

  RcvMsg     MsgType( *Excp )                                         +
             MsgDta( &MsgDta )                                        +
             MsgID( &MsgID )                                          +
             MsgF( &MsgF )                                            +
             MsgFLib( &MsgFLib )
  MonMsg     ( CPF0000 MCH0000 )

SndMsg:

  SndPgmMsg  MsgID( &MsgID )                                          +
             MsgF( &MsgFLib/&MsgF )                                   +
             MsgDta( &MsgDta )                                        +
             MsgType( *Escape )
  MonMsg     ( CPF0000 MCH0000 )

/*  ===============================================================  */
/*  = End of program                                              =  */
/*  ===============================================================  */

ENDPGM



File  : QCMDSRC
Member: CHKTCPIFC
Type  : CMD
Usage : CRTCMD CMD(lib/CHKTCPIFC) PGM(lib/CHKTCPIFC)
OS version: V5R1 以後(含)        

/*  ===============================================================  */
/*  = Command....... ChkTcpIfc                                    =  */
/*  = CPP........... ChkTcpIfc                                    =  */
/*  = Description... Check TCP/IP Interface Status                =  */
/*  =                                                             =  */
/*  = CrtCmd      Cmd( ChkTcpIfc )                                =  */
/*  =             Pgm( ChkTcpIfc )                                =  */
/*  =             SrcFile( YourSourceFile )                       =  */
/*  =                                                             =  */
/*  = For V5R1 and later use                                      =  */
/*  =                                                             =  */
/*  = Usage in CLP:                                               =  */
/*  =   ChkTcpIfc NETIFC( ip_address )                            =  */
/*  =   MONMSG CPF9898 => Possible error as following:            =  */
/*  =                     1. TCP/IP is not active.                =  */
/*  =                     2. Interface address is not active.     =  */
/*  =                     3. Interface address is not defined.    =  */
/*  ===============================================================  */
/*  = Date  : 2007/06/26                                          =  */
/*  = Author: Vengoal Chang                                       =  */
/*  ===============================================================  */
             CMD        PROMPT('Check TCP/IP Interface Status')

             PARM       KWD(NETIFC) TYPE(*CHAR) LEN(15) MIN(1) +
                          PROMPT('Network interface address')


於指令行下亦可以直接使用 CHKTCPIFC, 會輸出該介面的狀態或錯誤訊息
          
測試程式 CLP CHKTCPIFCT 
CRTCLPGM CHKTCPIFCT
CALL CHKTCPIFCT

例如系統中已設定 IP: 192.16.15.28
          未設定 IP: 192.16.15.27
          當所指定的 IP 無法使用時, 此指令會有一個錯誤訊息 ID CPF9898,
          程式中只要收到 CPF9898 即表示該 IP 無法使用          
          
PGM                                                                    
                                                                       
             DCL        VAR(&NETIFC) TYPE(*CHAR) LEN(15)               
                                                                       
             CHGVAR     VAR(&NETIFC) VALUE('172.16.15.27')             
             CHKTCPIFC  NETIFC(&NETIFC)                                
             MONMSG CPF9898 EXEC(DO)                                   
             SNDPGMMSG  MSG('Interface' *BCAT &NETIFC *BCAT 'is not +  
                          active or defined')                          
             ENDDO                                                     
                                                                       
             CHKTCPIFC  NETIFC('172.16.15.28')                         
                                                                       
ENDPGM                                                                 


                        




沒有留言: