Tools

34. TCP/IP サーバーの活動検査

TCP/IP での PING コマンドは単に TCP/IP 通信が可能であるか、どうかを検査するものであり
Telnet サーバーや Ftpサーバー、Httpサーバーが起動しているかどうかを検査するものではない。
ここで紹介する 「TCP/IP サーバーの活動検査 ( CHKSVR )」 コマンドは Well-Known サーバー、
つまり一般的な TCP/IP サーバーが活動中かどうかを検査するものである。
例えば、

  PGM                                                     
  CHKSVR     PORT(*HTTP)                                  
  MONMSG     MSGID(CPF9800) EXEC(DO)                      
  SNDPGMMSG  MSG('HTTP サーバーは活動していません。 ')    
  ENDDO                                                   
  ENDPGM                                                  

のような処理が可能である。

この CHKSVR コマンドはコマンド CHKSVR, CLP : CHKSVRCL と C/400: PORTCHK の3つから構成されている。

【 コマンド: CHKSVR 】
-----------------------------------------------------------------------------------
0001.00              CMD        PROMPT(' サーバー活動検査 ')                       
0002.00              PARM       KWD(PORT) TYPE(*CHAR) LEN(15) RSTD(*YES) +         
0003.00                           DFT(*HTTP) VALUES(*FTP *SSH *TELNET *SMTP +      
0004.00                           *HTTP *ALASKA *EXCLSVR *AUTOGUI *SPOOLWTR +      
0005.00                           *PHP *POP3 *IMAP *LDAP *SSL *DRDA *DDM +         
0006.00                           *DDMSSL *RUNRMTCMD *LPD *IMPLICIT +              
0007.00                           *SSLTELNET *IBMHTTPADM *IBMSSLHTPADM +           
0008.00                           *HPJETDIRECT) SPCVAL((*FTP 21) (*SSH 22) +       
0009.00                           (*TELNET 23) (*SMTP 25) (*HTTP 80) +             
0010.00                           (*ALASKA 3009) (*EXCLSVR 3005) (*AUTOGUI +       
0011.00                           3006) (*SPOOLWTR 3007) (*PHP 89) (*POP3 +        
0012.00                           110) (*IMAP 143) (*LDAP 389) (*SSL 443) +        
0013.00                           (*DRDA 446) (*DDM 447) (*DDMSSL 448) +           
0014.00                           (*RUNRMTCMD 512) (*LPD 515) (*IMPLICIT +         
0015.00                           990) (*TELNETSSL 992) (*IBMHTTPADM 2001) +       
0016.00                           (*IBMSSLHTPADM 2010) (*HPJETDIRECT 9100)) +      
0017.00                           PROMPT('TCP/IP サーバー ')                       
-----------------------------------------------------------------------------------
【 解説 】

このコマンド CHKSVR は PORT の入力値として *HTTP, *FTP, ... 等の文字列をパラメータとして
入力するのであるが実際に CLP: CHKSVRCL に渡される値は 80, 21, ... のように PORT 番号に
変換されて渡されるようになっている。
コンパイルは、

CRTCMD MYLIB/CHKSVR PGM(MYLIB/CHKSVRCL) SRCFILE(MYSRCLIB/QCMDSRC) AUT(*ALL)
【 CLP: CHKSVRCL 】
---------------------------------------------------------------------------------
0001.00              PGM        PARM(&SERVER)                                    
0002.00 /*---------------------------------------------------------*/            
0003.00 /*   CHKSVRCL :    サーバー活動検査                        */            
0004.00 /*---------------------------------------------------------*/            
0005.00              DCL        VAR(&MSG) TYPE(*CHAR) LEN(132)                   
0006.00              DCL        VAR(&SERVER) TYPE(*CHAR) LEN(15)                 
0007.00              DCL        VAR(&TYPE) TYPE(*CHAR) LEN(1)                    
0008.00              DCL        VAR(&PORT) TYPE(*CHAR) LEN(4)                    
0009.00              DCL        VAR(&RES) TYPE(*CHAR) LEN(4)                     
0010.00              MONMSG     MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))          
0011.00                                                                          
0012.00              RTVJOBA    TYPE(&TYPE)                                      
0013.00              CHGVAR     VAR(&PORT) VALUE(%SST(&SERVER 1 4))              
0014.00              CALL       PGM(ASNET.COM/PORTCHK) PARM(&PORT &RES)          
0015.00              IF         COND(&RES *NE 'TRUE') THEN(DO)                   
0016.00              SNDPGMMSG  MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA('PORT = +    
0017.00                           ' *CAT &PORT *TCAT +                           
0018.00                           ' は活動していません。 ') MSGTYPE(*ESCAPE)     
0019.00              ENDDO                                                       
0020.00              RETURN                                                      
0021.00                                                                          
0022.00  ERROR:      RCVMSG     MSGTYPE(*LAST) RMV(*NO) MSG(&MSG)                
0023.00  SNDMSG:                                                                 
024.00              IF         COND(&TYPE *EQ '0') THEN(DO)                
025.00              SNDPGMMSG  MSG(&MSG) TOMSGQ(*SYSOPR) MSGTYPE(*COMP)    
026.00              ENDDO                                                  
027.00              ELSE       CMD(DO)                                     
028.00              SNDPGMMSG  MSG(&MSG) TOMSGQ(*TOPGMQ) MSGTYPE(*DIAG)    
029.00              ENDDO                                                  
030.00              ENDPGM                                                 
----------------------------------------------------------------------------------
【 解説 】

CLP: CHKSVRCL ではコマンド CHKSVR から受け取ったPORT番号をプログラム PORTCHK に渡して
結果を受け取るだけである。
コンパイルは、

CRTCLPGM PGM(MYLIB/CHKSVRCL) SRCFILE(MYSRCLIB/QCLSRC) AUT(*ALL)
【 プログラム : PORTCHK 】
--------------------------------------------------------------------------------------
0001.00 /********************************************************************/        
0002.00 /*                                                                  */        
0003.00 /*   PORTCHK     :  PORT 検査                                       */        
0004.00 /*                                                                  */        
0005.00 /*          Office Quattro Co,.Ltd 2005/9/16 10:44:20 created       */        
0006.00 /*                                                                  */        
0007.00 /********************************************************************/        
0008.00 #include <stdio.h>                                                            
0009.00 #include <stdlib.h>                                                           
0010.00 #include <string.h>                                                           
0011.00 #include <netdb.h>                                                            
0012.00 #include <sys/types.h>                                                        
0013.00 #include <sys/socket.h>                                                       
0014.00 #include <netinet/in.h>                                                       
0015.00 #include <netinet/tcp.h>                                                      
0016.00 #include <arpa/inet.h>                                                        
0017.00                                                                               
0018.00 #define TRUE         0                                                        
0019.00 #define FALSE       -1                                                        
0020.00 #define SERV_HOST_ADDR "127.0.0.1"                                            
0021.00 #define MAXPORT   1024                                                        
0022.00 #define BUFLEN    1024                                                        
0023.00 #define SBUFLEN    256                                                        
0024.00                                                                              
0025.00 /***********************/                                                    
0026.00 /*     関数の定義      */                                                    
0027.00 /***********************/                                                    
0028.00                                                                              
0029.00 /********************************************************************/       
0030.00 /*            m  a  i  n --- main module of this pgm                */       
0031.00 /*------------------------------------------------------------------*/       
0032.00 /*   Parameter :  1. PORT[4]                                        */       
0033.00 /*                2. RESULT[4]                                      */       
0034.00 /*                                                                  */       
0035.00 /********************************************************************/       
0036.00 void main(int argc, char *argv[]){                                           
0037.00    struct sockaddr_in  addr;                                                 
0038.00    struct servent     *sent;                                                 
0039.00    int                fd, i, j, rtn, n;                                      
0040.00    char               buf[BUFLEN];                                           
0041.00    int    PORT;                                                              
0042.00    char   result[6];                                                         
0043.00                                                                              
0044.00 /*[ パラメータの取得 ]*/                                                     
0045.00       PORT = atoi(argv[1]);                                                  
0046.00      /*  ソケットの準備 */                                                   
0047.00      fd = socket(AF_INET, SOCK_STREAM, 0);                                   
0048.00      memset((char*)&addr, 0, sizeof(addr));                                    
0049.00      addr.sin_family = AF_INET;                                                
0050.00      addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR);                         
0051.00      addr.sin_port = htons((short)PORT);                                       
0052.00                                                                                
0053.00      memset(result, 0, sizeof(result));                                        
0054.00      /* サーバーと接続 */                                                      
0055.00      if((rtn = connect(fd, (struct sockaddr *)&addr, sizeof(addr))) == -1){    
0056.00        memcpy(result, "FALSE", 5);                                             
0057.00      }                                                                         
0058.00      else  memcpy(result, "TRUE ", 5);                                         
0059.00      close(fd);                                                                
0060.00      memcpy(argv[2], result, 5);                                               
0061.00      exit(0);                                                                  
0062.00                                                                                
0063.00 }                                                                              
--------------------------------------------------------------------------------------
【 解説 】

プログラム : PORTCHK は サーバーとして 127.0.0.1 と指定PORT番号を使ってアクセスして
通信可能かどうかを検査している。
127.0.0.1 とは自分自身を指している IPアドレスであり、すべての TCP/IP サーバーで共通である。
PORTCHK プログラムは 製品 EnterpriseServerHTTPサーバーの開始(STRHTPSVR) コマンドの
初期プログラムの中で利用されている。
HTTPサーバーの開始(STRHTPSVR) をユーザーが起動すると、まず PORTCHK によって
PORT = 80 が未使用で空いているかどうかが検査される。
PORT = 80 が空いていれば STRHTPSVR は開始PORT を 80 として開始するが、使用中であれば
PORT = 3009 で STRHTPSVR コマンドを開始する。
このように PORT の検査に利用されている。