

TCP/IP Programming Examples › Assembler Examples › Assembler TCP/IP Client Program
Assembler TCP/IP Client Program
TITLE 'Sample ASSEMBLER client TCP/IP program'
* ASMCLI RENT EP=ASMCLIEP
******************************************************************
* The following program is an example of a TCP/IP client *
* client program written in Assembler. *
* 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. *
******************************************************************
*---------------------------------------------------------------------*
MACRO
&LABEL. #SAVEREG
&LABEL. ST R12,0(,R13) Save R12
ST R14,4(,R13) Save R14
STM R2,R8,8(R13) Save R2-R8
LA R13,9*4(,R13)
MEND
*---------------------------------------------------------------------*
MACRO
&LABEL. #RESTREG
&LABEL. LA R12,9*4 Get register stack entry length
SR R13,R12 Get A(previous register stack entry)
L R12,0(,R13) Restore R12
L R14,4(,R13) Restore R14
LM R2,R8,8(R13) Restore R2-R8
MEND
*---------------------------------------------------------------------*
MACRO
&LABEL. MSGTXT &TXT.
LCLC &TMP.
&TMP. SETC '&SYSNDX'.
&LABEL. DC AL1(L2&TMP).
L1&TMP. DC C&TXT.
L2&TMP. EQU *-L1&TMP.
MEND
*---------------------------------------------------------------------*
ASMCLI CSECT
@MODE MODE=IDMSDC
#MOPT CSECT=ASMCLI,ENV=USER,RMODE=ANY,AMODE=ANY
ENTRY ASMCLIEP
ASMCLIEP DS 0H
BALR R12,0
BCTR R12,0
BCTR R12,0
USING ASMCLIEP,R12
B TCPSTART Branch around constants
*---------------------------------------------------------------------*
* Modify the following connection parameters before compiling -*
*---------------------------------------------------------------------*
DS 0F
DESTPORT DC F'12345' Known host port for connection
IPADOT DC CL13'255.255.00.01' Known IP address of host
DC CL4' ' filler
IPADOTL DC F'17' Total length of dotted string IPA
MAX_LOOP DC F'2' Maximum message count to send
*
TCPSTART DS 0H
*
#GETSTG TYPE=(USER,SHORT),ADDR=(R1),PLIST=*,INIT=X'0', X
LEN=WORKAREL
LR R11,R1
USING WORKAREA,R11
LA R13,REGSTACK R13 -> Register stack
* Initialize some WORKAREA fields
XR R5,R5
ST R5,ERRCOUNT
MVI OUTAREA,L'OUTAREAT
MVC OVRLOG,=X'8000000000'
MVC OVRLOGCO,=X'C000000000'
MVC WKCLEAR,=XL8'0F0F0F0F0F0F0F0F'
MVC TRTAB,=CL16'0123456789ABCDEF'
MVC TRTABX,=XL6'FAFBFCFDFEFF'
******************************************************************
* Create a socket in the communications domain *
******************************************************************
LA R1,MSG01 Display socket function.
L R15,=A(DISLINE)
BALR R14,R15
#SOCKET SOCKET, X
DOMAIN=AF@INET, X
TYPE=STREAM, X
PROTNUM=6, X
NEWSOCK=S_NEWSOC, X
RETCODE=RETCODE,ERRNO=ERRNO,RSNCODE=RSNCODE
LA R1,MSG02 Display results of socket function.
L R15,=A(DISRC)
BALR R14,R15 Display the 3 return codes.
CLC RETCODE,=F'0' Socket function successful?
BNE TCPCLOSE N. Close socket and exit.
******************************************************************
* Convert the IP address from dotted string format to binary. *
******************************************************************
LA R1,MSG12 Display INET_PTON socket function.
L R15,=A(DISLINE)
BALR R14,R15
#SOCKET INET_PTON,DOMAIN=AF@INET, X
IPADDRS=IPADOT,IPADDRSL=IPADOTL,IPADDR=HOSTIPA, X
RETCODE=RETCODE,ERRNO=ERRNO,RSNCODE=RSNCODE
LA R1,MSG13 Display INET_PTON results.
L R15,=A(DISRC)
BALR R14,R15 Display the 3 return codes.
******************************************************************
* Take the IP address and domain and resolve it through a name *
* server. If successful, return the information in a HOSTENT *
* structure. *
******************************************************************
LA R1,MSG14 Display GETHOSTBYADDR function.
L R15,=A(DISLINE)
BALR R14,R15
LA R2,BUFFER R2 -> buffer for host information
#SOCKET GETHOSTBYADDR,IPADDR=HOSTIPA,IPADDRL=4, X
DOMAIN=AF@INET,HOSTENTP=(R2), X
RETCODE=RETCODE,ERRNO=ERRNO,RSNCODE=RSNCODE
LA R1,MSG15 Display GETHOSTBYADDR results
L R15,=A(DISRC)
BALR R14,R15 Display the 3 return codes
CLC RETCODE,=F'0' GETHOSTBYADDR successful?
BNE TCPCLOSE N. Close socket and exit.
******************************************************************
* Prepare to connect to DESTPORT *
******************************************************************
LA R5,SOCKADDC R5 -> Socket address structure.
USING SOCK@IN,R5
MVI SIN@FAM,AF@INET Get the family,
MVC SIN@ADDR(4),HOSTIPA binary IPA, and
MVC SIN@PORT(2),DESTPORT+2 port number
LA R1,MSG03 for the Host connect.
L R15,=A(DISLINE) Display socket connect function.
BALR R14,R15
******************************************************************
* Connect to DESTPORT *
******************************************************************
#SOCKET CONNECT, X
SOCK=S_NEWSOC, X
SOCKADDR=(R5), X
SOCKADDL=SIN#LEN, X
RETCODE=RETCODE,ERRNO=ERRNO,RSNCODE=RSNCODE
LA R1,MSG04
L R15,=A(DISRC)
BALR R14,R15 Display the 3 return codes.
CLC RETCODE,=F'0' Connect successful?
BNE TCPCLOSE N. Close socket and exit.
******************************************************************
* Write and read two messages to/from DESTPORT *
******************************************************************
WRLOOP DS 0H
L R5,LOOP_CNT Add 1
LA R5,1(R5) to current
ST R5,LOOP_CNT message count
ST R5,WORK1 and
UNPK WORK2(9),WORK1(5) make
NC WORK2(8),WKCLEAR it
TR WORK2(8),TRTAB displayable.
MVC BUFTXT_S(1),WORK2+7
LA R7,BUFFER_A R7 -> buffer array.
* Build client message.
******************************************************************
* Send a message to the listener *
******************************************************************
MVC BUFTXT_M(33),=C'ASMCLI TCP/IP test message number'
MVC BUFTXT_B(1),=C' ' Blank character.
MVC BUFLEN(4),=F'43' Length of message text.
MVC WK_LEN(4),=F'47' Total length of message.
BAL R4,TCPWRITE Send message to listener.
*
******************************************************************
* Read the first 4 bytes of reply: contains the remaining length *
******************************************************************
LA R5,4
ST R5,WK_LEN
XR R5,R5
ST R5,BUFLEN
LA R7,BUFFER_A R7 -> buffer array.
BAL R4,TCPREAD Perform socket read function.
*
CLC BUFLEN(4),=F'80' Incoming buffer less than 80?
BL READLIS Y. Read listener reply.
LA R1,MSG11 N. Reply too long,issue
L R15,=A(DISLINE) error message
BALR R14,R15 and
B TCPCLOSE close socket.
READLIS DS 0H
MVC WK_LEN,BUFLEN Reply msg length=read length.
LA R7,BUFFER_A+4 R7 -> reply from listener.
BAL R4,TCPREAD Read listener reply.
*
CLC MAX_LOOP,LOOP_CNT All messages sent?
BH WRLOOP N. loop until done.
B TCPCLOSE Y. Close socket and exit.
******************************************************************
* Routine to read a message from DESTPORT *
******************************************************************
TCPREAD DS 0H
LA R1,MSG05 Display socket read function.
L R15,=A(DISLINE)
BALR R14,R15
#SOCKET READ,SOCK=S_NEWSOC,BUFFER=(R7), X
RETLEN=RETLEN,BUFFERL=WK_LEN, X
RETCODE=RETCODE,ERRNO=ERRNO,RSNCODE=RSNCODE
*
LA R1,MSG06 Display results of read.
L R15,=A(DISRC)
BALR R14,R15 Display the 3 return codes.codes
CLC RETCODE,=F'0' Successful read?
BNE TCPCLOSE N. Error close socket.
A R7,RETLEN Adjust buffer array pointer
L R5,WK_LEN and
S R5,RETLEN read length
ST R5,WK_LEN with reply length.
CLI WK_LEN,0 Read done?
BNE TCPREAD N. Read some remainder.
BR R4 Y. Return.
******************************************************************
* Routine to send a message to DESTPORT *
******************************************************************
TCPWRITE DS 0H Display socket write function.
LA R1,MSG07
L R15,=A(DISLINE)
BALR R14,R15
#SOCKET WRITE,SOCK=S_NEWSOC,BUFFER=(R7), X
RETLEN=RETLEN,BUFFERL=WK_LEN, X
RETCODE=RETCODE,ERRNO=ERRNO,RSNCODE=RSNCODE
*
LA R1,MSG08 Display results of socket write.
L R15,=A(DISRC)
BALR R14,R15 Display the 3 return codes.
*
CLC RETCODE,=F'0' Write successful?
BNE TCPCLOSE N. Close socket and exit.
MVC OUTAREA,WK_LEN+3 Message text length.
MVC OUTAREAT,BUFTXT80 Message text.
LA R1,OUTAREA Display buffer contents
L R15,=A(DISLINE)
BALR R14,R15
*
A R7,RETLEN Adjust buffer array
L R5,WK_LEN and
S R5,RETLEN write length
ST R5,WK_LEN with message length.
CLI WK_LEN,0 Anything left to write?
BNE TCPWRITE Y. Loop back.
BR R4 N. Return.
******************************************************************
* Close the socket and exit *
******************************************************************
TCPCLOSE DS 0H
LA R1,MSG09 Display closing socket.
L R15,=A(DISLINE)
BALR R14,R15 Display the 3 return codes.
#SOCKET CLOSE,SOCK=S_NEWSOC, X
RETCODE=RETCODE,ERRNO=ERRNO,RSNCODE=RSNCODE
*
LA R1,MSG10 Display socket close function.
L R15,=A(DISRC)
BALR R14,R15 Display the 3 return codes.
*
MVC OUTAREAT(41),MSG99+1 Display ASMCLI temrimation msg.
L R5,ERRCOUNT Get number of socket errors
ST R5,WORK1 and
UNPK WORK2(9),WORK1(5) make
NC WORK2(8),WKCLEAR it
TR WORK2(8),TRTAB displayable
MVC ERRINDEC(4),WORK2+4 on the
MVC OUTAREAT+41(4),ERRINDEC terminal.
IC R3,MSG99
LA R3,4(R3)
STC R3,OUTAREA
LR R1,R3
LA R3,OUTAREAT
#LINEOUT OUTLEN=(R1),OUTAREA=(R3),OPTNS=(NOWAIT,TRLATIN)
*
LA R3,OUTAREA
#WTL MSGID=M#999043,MSGDICT=NO,OVRIDES=OVRLOG, X
PARMS=((R3)),RGSV=(R2-R8)
*
#RETURN
#BALI
*
DROP R12
LTORG
TITLE 'ASMCLI - DISRC : DISPLAY THE RETURN CODES'
*---------------------------------------------------------------------*
*- Routine to display the 3 return values from any TCP/IP calls. -*
*- Input : RETCODE, ERRNO and RSNCODE from the WORKAREA -*
*- R1 -> String to start with (e.g. MSGTXT format) -*
*---------------------------------------------------------------------*
DISRC DS 0H
#SAVEREG Save the caller's registers
*
LR R12,R15
USING DISRC,R12
*
MVI OUTAREA,L'OUTAREAT
MVI OUTAREAT,C' '
MVC OUTAREAT+1(L'OUTAREAT-1),OUTAREAT
*
XR R2,R2
IC R2,0(,R1) Get message length
BCTR R2,0 -1 for EX
EX R2,DISRCEX Copy text
LA R2,1+1+OUTAREAT(R2) Point to next free space
*
CLC RETCODE,=F'0'
BE DISRC00
L R3,ERRCOUNT
LA R3,1(R3)
ST R3,ERRCOUNT
DISRC00 DS 0H
MVC WORK1(4),RETCODE
UNPK WORK2(9),WORK1(5)
NC WORK2(8),WKCLEAR
TR WORK2(8),TRTAB
MVC 0(8,R2),=CL8'RETCODE='
MVC 8(8,R2),WORK2
*
L R15,ERRNO
CVD R15,WORK1
OI WORK1+7,X'0F'
UNPK WORK2(10),WORK1+2(6)
LA R14,WORK2
LA R15,9
DISRC01 DS 0H
CLI 0(R14),C'0'
BNE DISRC02
MVI 0(R14),C' '
LA R14,1(,R14)
BCT R15,DISRC01
DISRC02 DS 0H
MVC 17(8,R2),=CL6'ERRNO='
MVC 23(8,R2),WORK2+2
*
MVC WORK1(4),RSNCODE
UNPK WORK2(9),WORK1(5)
NC WORK2(8),WKCLEAR
TR WORK2(8),TRTAB
MVC 32(8,R2),=CL8'RSNCODE='
MVC 40(8,R2),WORK2
*
LA R1,OUTAREA
L R15,=A(DISLINE)
BALR R14,R15
*
#RESTREG Restore the caller's registers
BR R14
*
DROP R12
*
DISRCEX MVC OUTAREAT(0),1(R1) COPY TEXT
LTORG
TITLE 'ASMCLI - DISLINE : Write message line to log'
*---------------------------------------------------------------------*
*- Subroutine to write a message line to the log. -*
*- Input : R1 = A(output message) (first byte = message length) -*
*---------------------------------------------------------------------
DISLINE DS 0H
#SAVEREG Save the caller's registers
*
LR R12,R15
USING DISLINE,R12
LR R3,R1 Get parm in R3
*
#WTL MSGID=M#999043,MSGDICT=NO,OVRIDES=OVRLOG, X
PARMS=((R3)),RGSV=(R2-R8)
*
#RESTREG Restore the caller's registers
*
BR R14
*
DROP R12
*
M#999043 DC PL4'9990430'
*
MSG01 MSGTXT 'Creating Socket.'
MSG02 MSGTXT 'SOCKET call:'
MSG03 MSGTXT 'Connecting: '
MSG04 MSGTXT 'CONNECT call:'
MSG05 MSGTXT 'Starting read.'
MSG06 MSGTXT 'READ call:'
MSG07 MSGTXT 'Starting write.'
MSG08 MSGTXT 'WRITE call:'
MSG09 MSGTXT 'Closing Socket.'
MSG10 MSGTXT 'CLOSE call:'
MSG11 MSGTXT 'Data length too long.'
MSG12 MSGTXT 'Calling INET_PTON.'
MSG13 MSGTXT 'INET_PTON call:'
MSG14 MSGTXT 'Calling GETHOSTBYADDR.'
MSG15 MSGTXT 'GETHOSTBYADDR call:'
MSG99 MSGTXT 'Program ASMCLI terminated. Error count = '
*
LTORG
*
*
TITLE 'ASMCLI - WORK AREA'
WORKAREA DSECT
*----------------------------------*
*- DYNAMIC DATA -*
*----------------------------------*
SYSPLIST DS 16F
REGSTACK DS 32F
*
DS 0D
WORK1 DC XL10'00'
DS 0D
WORK2 DC XL10'00' AT LEAST 10 BYTES DOUBLEWORD ALIGNED
*
*
HOSTIPA DS F Binary IPA address of host
HOSTENTP DS F Pointer to HOSTENT structure
LOOP_CNT DS F Message counter
WK_LEN DS F Length for read or write
ERRCOUNT DS F Number of socket errors
ERRINDEC DS CL4 Number of socket errors decimal
*
*
SOCKADDC DS (SIN#LEN)X SOCKADDR for the client
SOCKDESN DS F
S_NEWSOC DS F
RETLEN DS F
RETCODE DS F
ERRNO DS F
RSNCODE DS F
*
*
OUTAREA DS X
OUTAREAT DC CL80' ' OUTPUT AREA
DS 0F
BUFFER DS CL84
ORG BUFFER
BUFLEN DS F
BUFTXT80 DS CL80
ORG BUFTXT80
BUFTXT_M DS CL33 Message text
BUFTXT_B DS CL1 Blank character
BUFTXT_S DS CL5 Message sequence number
BUFTXT_F DS CL41 Filler
ORG BUFFER
BUFFER_A DS CL84
*
*
*
*----------------------------------*
*- STATIC DATA -*
*----------------------------------*
*
OVRLOG DS X'8000000000' #WTL TO LOG ONLY
OVRLOGCO DS X'C000000000' #WTL TO LOG + CONSOLE
*
*
WKCLEAR DS XL8'0F0F0F0F0F0F0F0F'
TRTAB DS CL16'0123456789ABCDEF'
TRTABX DS XL6'FAFBFCFDFEFF'
*
WORKAREL EQU *-WORKAREA
*
*---------------------------------------------------------------------*
*- TCP/IP TABLES -*
*---------------------------------------------------------------------*
*
#SOCKET TCPIPDEF
#SOCKET ERRNOS
*
END ASMCLIEP
Copyright © 2014 CA.
All rights reserved.
 
|
|