Previous Topic: CA ADS ExamplesNext Topic: CA ADS TCP/IP Generic Listener Server Program


CA ADS TCP/IP Client Program

******************************************************************
* The following program is an example of a TCP/IP client         *
* program written in ADS.                                        *
* The processing is the following:                               *
*  - Create a socket for the client program.                     *
*  - Convert the known dotted string format IPA to binary.       *
*  -   (Host IPA is defined in IPADOT, see below.)               *
*  - Find host information for connection.                       *
*  -   (Host port is defined in DESTPORT, see below.)            *
*  - Establish a connection to the host listener.                *
*  - Send message 1 to the listener (first 4 bytes = data length)*
*  - Read message 1 from  listener (first 4 bytes = data length) *
*  - Send message 2 to the listener (first 4 bytes = data length)*
*  - Read message 2 from  listener (first 4 bytes = data length) *
*  - Close socket and exit.                                      *
******************************************************************
***               A D S C L I                                  ***
*** IDD input                                                  ***
******************************************************************
       SET OPTIONS DEFAULT IS ON INPUT 1 THRU 80.

ADD RECORD ADSCLI-WORK-RECORD.
    02 WK-RETCD                 PIC S9(8) COMP.
    02 WK-ERRNO                 PIC S9(8) COMP.
    02 WK-RSNCD                 PIC S9(8) COMP.
    02 SOCKDESC                 PIC S9(8) COMP.
    02 LOOP-COUNT               PIC S9(8) COMP.
    02 RETLEN                   PIC S9(8) COMP.
    02 WK-LENGTH                PIC S9(8) COMP.
    02 WK-SUBSCRIPT             PIC S9(8) COMP.
    02 HOSTIPA                  PIC  9(8) COMP.
    02 HOSTENTP                 PIC  9(8) COMP.
    02 MAX-LOOP                 PIC  9(4) COMP VALUE 2.
    02 DEST-PORT                PIC  9(8) COMP VALUE 12345.
    02 IPA-HOST                 PIC X(12) VALUE '255.255.25.2'.
    02 FILLER                   PIC X(4) VALUE SPACES.
    02 IPA-HOSTL                PIC S9(8) COMP VALUE 16.
ADD RECORD ADSCLI-BUFFER-RECORD.
    02 BUFFER                   PIC X(84).
    02 BUFFER-REDEF1      REDEFINES BUFFER.
       03 BUFLEN                PIC 9(8) COMP.
       03 BUFTXT80              PIC X(80).
       03 BUFTXT80-REDEF  REDEFINES BUFTXT80.
          04 BUFTXT-MSG         PIC X(29).
          04 BUFTXT-SEQ         PIC X(5).
          04 BUFTXT-BLANK       PIC X(1).
          04 BUFTXT-FILLER      PIC X(45).
    02 BUFFER-REDEF2      REDEFINES BUFFER.
       03 BUFFER-ARRAY          PIC X(1) OCCURS 84.

ADD PROCESS ADSCLI-PM MODULE SOURCE FOLLOWS
    WRITE TO LOG MESSAGE TEXT = 'ADSCLI: Starting dialog.'.

    !*******************************************************************
    ! Create a socket                                                  *
    !*******************************************************************
    IF (SOCKET(SOCKET-FUNCTION-SOCKET,
               SOCKET-RETCD,
               SOCKET-ERRNO,
               SOCKET-RSNCD,
               SOCKET-FAMILY-AFINET,
               SOCKET-TYPE-STREAM,
               SOCKET-PROTOCOL-TCP,
               SOCKDESC) EQ 0)
    THEN DO.
       WRITE TO LOG MESSAGE TEXT = 'ADSCLI: SOCKET successful.'.
       END.
    ELSE DO.
       WRITE TO LOG MESSAGE TEXT = 'ADSCLI: SOCKET error'.
       CALL TCPERROR.
       LEAVE ADS.
       END.

    !*******************************************************************
    ! Convert the IP address from dotted string format to binary.      *
    !*******************************************************************
    IF (SOCKET(SOCKET-FUNCTION-INETPTON,
               SOCKET-RETCD,
               SOCKET-ERRNO,
               SOCKET-RSNCD,
               SOCKET-FAMILY-AFINET,
               IPA-HOST,
               IPA-HOSTL,
               HOSTIPA) EQ 0)
    THEN DO.
       WRITE TO LOG MESSAGE TEXT = 'ADSCLI: INETPTON successful.'.
       END.
    ELSE DO.
       WRITE TO LOG MESSAGE TEXT = 'ADSCLI: INETPTON error.'.
       CALL TCPERROR.
       CALL TCPCLOSE.
       LEAVE ADS.
       END.
    !*******************************************************************
    ! Take the IP address and domain and resolve it through a name     *
    ! server. If successful, return the information in a HOSTENT       *
    ! structure.                                                       *
    !*******************************************************************
    IF (SOCKET(SOCKET-FUNCTION-GETHOSTBYADDR,
               SOCKET-RETCD,
               SOCKET-ERRNO,
               SOCKET-RSNCD,
               HOSTIPA,
               SOCKET-IPADDR4L,
               SOCKET-FAMILY-AFINET,
               HOSTENTP) EQ 0)
    THEN DO.
       WRITE TO LOG MESSAGE TEXT = 'ADSCLI:GETHOSTBYADDR successful.'.
       END.
    ELSE DO.
       WRITE TO LOG MESSAGE TEXT = 'ADSCLI: GETHOSTBYADDR error'.
       CALL TCPERROR.
       CALL TCPCLOSE.
       LEAVE ADS.
       END.

    MOVE SOCKET-FAMILY-AFINET TO SIN-FAMILY.
    MOVE DEST-PORT            TO SIN-PORT-NUMBER.
    MOVE HOSTIPA              TO SIN-ADDRESS.
    MOVE LOW-VALUES           TO SIN-ZEROS.
    IF (SOCKET(SOCKET-FUNCTION-CONNECT,
               SOCKET-RETCD,
               SOCKET-ERRNO,
               SOCKET-RSNCD,
               SOCKDESC,
               SOCKADDR-IN,
               SOCKADDR-IN-LENGTH) EQ 0)
    THEN DO.
       WRITE TO LOG MESSAGE TEXT = 'ADSCLI: CONNECT successful.'.
       END.
    ELSE DO.
       WRITE TO LOG MESSAGE TEXT = 'ADSCLI: CONNECT error.'.
       CALL TCPERROR.
       CALL TCPCLOSE.
       LEAVE ADS.
       END.

    !*******************************************************************
    ! Loop of write and read of messages with the server               *
    !*******************************************************************
    MOVE 1 TO LOOP-COUNT.
    WHILE LOOP-COUNT LE MAX-LOOP
    REPEAT.

       MOVE 'ADSCLI test message number ' TO BUFTXT-MSG.
       MOVE LOOP-COUNT             TO BUFTXT-SEQ.
       MOVE ' '                    TO BUFTXT-BLANK.
       MOVE 37 TO BUFLEN.
       MOVE 41 TO WK-LENGTH.
       MOVE 1  TO WK-SUBSCRIPT.
       CALL TCPWRITE.

     ! Read the first 4 bytes: will contain the remaining length
       MOVE 4  TO WK-LENGTH.
       MOVE 0  TO BUFLEN.
       MOVE 1  TO WK-SUBSCRIPT.
       CALL TCPREAD.

     ! Read the remaining data (maximum 80 characters are allowed)
       IF (BUFLEN GT 80)
       THEN DO.
          WRITE TO LOG MESSAGE TEXT = 'ADSCLI: Data length too long.'.
          CALL TCPCLOSE.
          LEAVE ADS.
          END.

       MOVE BUFLEN TO WK-LENGTH.
       MOVE 5      TO WK-SUBSCRIPT.
       CALL TCPREAD.

       SNAP RECORD (ADSCLI-BUFFER-RECORD).

       ADD 1 TO LOOP-COUNT.
       END. ! WHILE LOOP-COUNT

    !*******************************************************************
    ! Loop completed. Close the socket and exit the program.           *
    !*******************************************************************
    WRITE TO LOG MESSAGE TEXT = 'ADSCLI: READ/WRITE loop completed.'.

    CALL TCPCLOSE.

    WRITE TO LOG MESSAGE TEXT = 'ADSCLI: Dialog ended successfully.'.
    LEAVE ADS.

    !*******************************************************************
    ! Subroutine to read a message from the client                     *
    !*******************************************************************
    DEFINE SUBROUTINE TCPREAD.
       WHILE WK-LENGTH GT 0 REPEAT.
          IF (SOCKET(SOCKET-FUNCTION-READ,
                     SOCKET-RETCD,
                     SOCKET-ERRNO,
                     SOCKET-RSNCD,
                     SOCKDESC,
                     BUFFER-ARRAY(WK-SUBSCRIPT),
                     WK-LENGTH,
                     RETLEN) EQ 0)
          THEN DO.
             WRITE TO LOG MESSAGE TEXT = 'ADSCLI: READ successful.'.
             END.
          ELSE DO.
             WRITE TO LOG MESSAGE TEXT = 'ADSCLI: READ error.'.
             CALL TCPERROR.
             CALL TCPCLOSE.
             LEAVE ADS.
             END.
          IF (RETLEN = 0)
          THEN DO.
             WRITE TO LOG MESSAGE TEXT = 'ADSCLI: READ 0 bytes'.
             CALL TCPCLOSE.
             LEAVE ADS.
             END.
          ADD RETLEN TO WK-SUBSCRIPT.
          SUBTRACT RETLEN FROM WK-LENGTH.
          END. ! READ LOOP
       GOBACK.

    !*******************************************************************
    ! Subroutine to send a message to the client                       *
    !*******************************************************************
    DEFINE SUBROUTINE TCPWRITE.
       WHILE WK-LENGTH GT 0 REPEAT.
          IF (SOCKET(SOCKET-FUNCTION-WRITE,
                     SOCKET-RETCD,
                     SOCKET-ERRNO,
                     SOCKET-RSNCD,
                     SOCKDESC,
                     BUFFER-ARRAY(WK-SUBSCRIPT),
                     WK-LENGTH,
                     RETLEN) EQ 0)
          THEN DO.
             WRITE TO LOG MESSAGE TEXT = 'ADSCLI: WRITE successful.'.
             END.
          ELSE DO.
             WRITE TO LOG MESSAGE TEXT = 'ADSCLI: WRITE error.'.
             CALL TCPERROR.
             CALL TCPCLOSE.
             LEAVE ADS.
             END.
          IF (RETLEN = 0)
          THEN DO.
             WRITE TO LOG MESSAGE TEXT = 'ADSCLI: WRITE 0 bytes.'.
             CALL TCPCLOSE.
             LEAVE ADS.
             END.
          ADD RETLEN TO WK-SUBSCRIPT.          SUBTRACT RETLEN FROM WK-LENGTH.
          END. ! WRITE LOOP
       GOBACK.

    !*******************************************************************
    ! Subroutine to close the socket                                   *
    !*******************************************************************
    DEFINE SUBROUTINE TCPCLOSE.
       IF (SOCKET(SOCKET-FUNCTION-CLOSE,
                  SOCKET-RETCD,
                  SOCKET-ERRNO,
                  SOCKET-RSNCD,
                  SOCKDESC) EQ 0)
       THEN DO.
          WRITE TO LOG MESSAGE TEXT = 'ADSCLI: CLOSE successful.'.
          END.
       ELSE DO.
          WRITE TO LOG MESSAGE TEXT = 'ADSCLI: CLOSE error.'.
          CALL TCPERROR.
          LEAVE ADS.
          END.
       GOBACK.

    !*******************************************************************
    ! Subroutine to process the socket calls errors                    *
    !*******************************************************************
    DEFINE SUBROUTINE TCPERROR.
       MOVE SOCKET-RETCD TO WK-RETCD.
       MOVE SOCKET-ERRNO TO WK-ERRNO.
       MOVE SOCKET-RSNCD TO WK-RSNCD.
       SNAP RECORD (ADSCLI-WORK-RECORD).
       GOBACK.

MSEND.