TCPIP SOCKET RPG 程式範例(Echo server)
前期電子報介紹 RPG SOCKET 程式的參考資訊,各位先進應該看完了吧。
本期我以一個 Echo server 來當作範例,並提供一隻 echo client rpg 程式讓您測試,
當然您也可以直接利用 telnet 程式測試。
此 Echo server socket 程式啟動後會依照所傳參數(AS/400 host ip 及 port number),
將之 bind 連結到 socket 中,然後 listen 傾聽所指定的 port 有無 client 端連線
需求,如果有就 accept 接受連結,接著傳送連結訊息至 client 端,接著等待 client
輸入任何字串,當 client 端輸入訊息並傳送出去後,Echo server 收到厚利即將原字串
傳回 client 端。當 client 輸入 QUIT 字串時,Echo server 會將此連線中斷,並等待
下一個 client 提出連線需求。
整個流程如下:
Echo Server Echo Client
Create socket Create socket
Bind Bind(可有可無)
Listen
--> Accept <--------- Connect
|
| Send ---------> Receive
| /\ ||
| || \/
| Receive <---------- Send
| "QUIT" "QUIT"
| || ||
| \/ \/
| Close Close
| Client socket
| ||
| \/
------
File : QRPGLESRC
Member: SOCKETSVRR (Echo Server)
Type : RPGLE
Usage : CRTBNDRPG SOCKETSVRR
OS version: V4R1
H DFTACTGRP(*NO) ACTGRP(*NEW) BNDDIR('QC2LE')
H Debug
D Cmd PR ExtPgm('QCMDEXC')
D command 200A const
D length 15P 5 const
*-------------------------------------------------------------------
* prototype definitions
*-------------------------------------------------------------------
D @__errno PR * ExtProc('__errno')
D strerror PR * ExtProc('strerror')
D errnum 10I 0 value
D perror PR ExtProc('perror')
D comment * value options(*string)
D errno PR 10I 0
*-------------------------------------------------------------------
* socket C API prototype definitions
*-------------------------------------------------------------------
D getservbyname PR * ExtProc('getservbyname')
D service_name * value options(*string)
D protocol_name * value options(*string)
D p_servent S *
D servent DS based(p_servent)
D s_name *
D s_aliases *
D s_port 10I 0
D s_proto *
D inet_addr PR 10U 0 ExtProc('inet_addr')
D address_str * value options(*string)
D INADDR_NONE C CONST(4294967295)
D* any address available
D INADDR_ANY C CONST(0)
D inet_ntoa PR * ExtProc('inet_ntoa')
D internet_addr 10U 0 value
D p_hostent S *
D hostent DS Based(p_hostent)
D h_name *
D h_aliases *
D h_addrtype 10I 0
D h_length 10I 0
D h_addr_list *
D p_h_addr S * Based(h_addr_list)
D h_addr S 10U 0 Based(p_h_addr)
D p_linger S *
D linger DS BASED(p_linger)
D l_onoff 10I 0
D l_linger 10I 0
D gethostbyname PR * extproc('gethostbyname')
D host_name * value options(*string)
D socket PR 10I 0 ExtProc('socket')
D addr_family 10I 0 value
D type 10I 0 value
D protocol 10I 0 value
D AF_INET C CONST(2)
D SOCK_STREAM C CONST(1)
D IPPROTO_IP C CONST(0)
D bind PR 10I 0 ExtProc('bind')
D Sock_Desc 10I 0 Value
D p_Address * Value
D AddressLen 10I 0 Value
D Select PR 10I 0 extproc('select')
D max_desc 10I 0 VALUE
D read_set * VALUE
D write_set * VALUE
D except_set * VALUE
D wait_Time * VALUE
D listen PR 10I 0 ExtProc('listen')
D SocketDesc 10I 0 Value
D Back_Log 10I 0 Value
D accept PR 10I 0 ExtProc('accept')
D Sock_Desc 10I 0 Value
D p_Address * Value
D p_AddrLen 10I 0
D connect PR 10I 0 ExtProc('connect')
D sock_desc 10I 0 value
D dest_addr * value
D addr_len 10I 0 value
D p_sockaddr S *
D sockaddr DS based(p_sockaddr)
D sa_family 5I 0
D sa_data 14A
D sockaddr_in DS based(p_sockaddr)
D sin_family 5I 0
D sin_port 5U 0
D sin_addr 10U 0
D sin_zero 8A
D send PR 10I 0 ExtProc('send')
D sock_desc 10I 0 value
D buffer * value
D buffer_len 10I 0 value
D flags 10I 0 value
D recv PR 10I 0 ExtProc('recv')
D sock_desc 10I 0 value
D buffer * value
D buffer_len 10I 0 value
D flags 10I 0 value
D close PR 10I 0 ExtProc('close')
D sock_desc 10I 0 value
D setsockopt PR 10I 0 ExtProc('setsockopt')
D SocketDesc 10I 0 Value
D Opt_Level 10I 0 Value
D Opt_Name 10I 0 Value
D Opt_Value * Value
D Opt_Len 10I 0 Value
D translate PR ExtPgm('QDCXLATE')
D length 5P 0 const
D data 32766A options(*varsize)
D table 10A const
D die PR
D peMsg 256A const
D* socket layer
D SOL_SOCKET C CONST(-1)
D* re-use local address
D SO_REUSEADDR C 55
D* linger upon close
D SO_LINGER C 30
D msg S 50A
D sock S 10I 0
D port S 5U 0
D addrlen S 10I 0
D ch S 1A
D local s 32A
D localportc s 5A
D IPLocal s 10U 0
D p_bindto S *
D p_Connfrom S *
D lsock S 10I 0
D csock S 10I 0
D RC S 10I 0
D Request S 50A
D ReqLen S 10I 0
D RecBuf S 50A
D RecLen S 10I 0
D on S 10I 0 inz(1)
D err S 10I 0
D clientip S 17A
D line S 80A
D ling S *
D linglen S 10I 0
C*************************************************
C* The user will supply a hostname and port
C* for client connect
C*************************************************
c *entry plist
c parm local
c parm localportc
c eval *inlr = *on
c exsr MakeListener
c dow 1 = 1
c exsr AcceptConn
c exsr TalkToClient
c callp close(csock)
c enddo
C*===============================================================
C* This subroutine sets up a socket to listen for connections
C* include socket, bind, listen API
C*===============================================================
CSR MakeListener begsr
*
C* Get the 32-bit network IP address for
C* local that was supplied by the user:
*
c If local <> *blanks
c eval IPLocal = inet_addr(%trim(local))
c if IPLocal = INADDR_NONE
c eval p_hostent = gethostbyname(%trim(local))
c if p_hostent = *NULL
c callp die('Unable to find that local!')
c return
c endif
c eval IPLocal = h_addr
c endif
c Else
c eval IPlocal = INADDR_ANY
c EndIf
c
c if localportc <> *blanks
c move localportc port
c else
c callp die('Wrong port specified !')
c return
c endif
C* Create a socket
c eval sock = socket(AF_INET: SOCK_STREAM:
c IPPROTO_IP)
c if sock < 0
c callp die('socket(): ' + %str(strerror(errno)))
c return
c endif
C*** Tell socket that we want to be able to re-use the server
C*** port without waiting for the MSL timeout:
c callp setsockopt(sock: SOL_SOCKET:
c SO_REUSEADDR: %addr(on): %size(on))
C* create space for a linger structure
c eval linglen = %size(linger)
c alloc linglen ling
c eval p_linger = ling
C* tell socket to only linger for 2 minutes, then discard:
c eval l_onoff = 1
c eval l_linger = 1
c callp setsockopt(lsock: SOL_SOCKET: SO_LINGER:
c ling: linglen)
C* bind the socket to local port , of any IP address
C* Allocate some space for some socket addresses
c eval addrlen = %size(sockaddr_in)
c alloc addrlen p_bindto
c alloc addrlen p_connfrom
c eval p_sockaddr = p_bindto
c move localportc port
c eval sin_family = AF_INET
c eval sin_addr = IPLocal
c eval sin_port = port
c eval sin_zero = *ALLx'00'
c if bind(sock: p_bindto: addrlen) < 0
c eval err = errno
c callp close(sock)
c callp die('bind(): ' + %str(strerror(err)))
c return
c endif
C* Indicate that we want to listen for connections
c if listen(sock: 5) < 0
c eval err = errno
c callp close(sock)
c callp die('listen(): ' + %str(strerror(err)))
c return
c endif
C
CSR endsr
C*===============================================================
C* This subroutine accepts a new socket connection
C*===============================================================
CSR AcceptConn begsr
C*------------------------
c dou addrlen = %size(sockaddr_in)
C* Accept the next connection.
c eval addrlen = %size(sockaddr_in)
c eval csock = accept(sock: p_connfrom: addrlen)
c if csock < 0
c eval err = errno
c callp close(sock)
c callp die('accept(): ' + %str(strerror(err)))
c return
c endif
C* tell socket to only linger for 2 minutes, then discard:
c eval l_onoff = 1
c eval l_linger = 120
c callp setsockopt(csock: SOL_SOCKET: SO_LINGER:
c ling: linglen)
C* If socket length is not 16, then the client isn't sending the
C* same address family as we are using... that scares me, so
C* we'll kick that guy off.
c if addrlen <> %size(sockaddr_in)
c callp close(csock)
c endif
c enddo
c eval p_sockaddr = p_connfrom
c eval clientip = %str(inet_ntoa(sin_addr))
c clientip dsply
C*------------------------
CSR endsr
C*===============================================================
C* This does a quick little conversation with the connecting
c* client.
C*===============================================================
CSR TalkToClient begsr
C*------------------------
c eval line ='Connection from ' +
c %trim(clientip)
c exsr WrLine
c eval line ='Please enter your name now!'
c exsr WrLine
c eval recbuf = *blanks
c Dow %SubSt(recbuf : 1 : 4) <> 'QUIT'
c exsr RdLine
c If reclen > 0
c eval line = 'Server response: ' + recbuf
c exsr WrLine
c EndIf
c Enddo
c eval line ='Goodbye '
c exsr WrLine
c dealloc(E) p_connfrom
c callp Cmd('DLYJOB DLY(1)': 200)
C*------------------------
CSR endsr
C*===============================================================
C* This subroutine send data to socket client with CRLF
C*===============================================================
CSR WrLine begsr
c eval reqlen = %len(%trim(line))
c callp Translate(reqlen: line: 'QTCPASC')
c eval line = %trim(line) + X'0D0A'
c eval reqlen = %len(%trim(line))
c* 'dmptxt' dump
c eval rc= send(csock: %addr(line): reqlen:0)
c if rc < reqlen
c callp close(csock)
c callp die('Unable to send entire request!')
c return
c endif
CSR endsr
C*===============================================================
C* This subroutine receives what we send to server and
C* displays it on the screen using the DSPLY op-code
C*===============================================================
CSR RdLine begsr
C*------------------------
C*************************************************
C* Receive one line of text from the socket client
C* note that "lines of text" vary in length,
C* but always end with the ASCII values for CR
C* and LF. CR = x'0D' and LF = x'0A'
C*
C* The easiest way for us to work with this data
C* is to receive it one byte at a time until we
C* get the LF character. Each time we receive
C* a byte, we add it to our receive buffer.
C*************************************************
c eval reclen = 0
c eval recbuf = *blanks
c dou reclen = 80 or ch = x'0A'
c eval rc = recv(csock: %addr(ch): 1: 0)
c if rc < 1
c 'rcvfail' dsply
c callp close(csock)
c callp die('Unable to receive data !')
c return
c endif
c if ch<>x'0D' and ch<>x'0A'
c eval reclen = reclen + 1
c eval %subst(recbuf:reclen:1) = ch
c endif
c enddo
C*************************************************
C* translate the line of text into EBCDIC
C* (to make it readable) and display it
C*************************************************
c if reclen > 0
c callp Translate(reclen: recbuf: 'QTCPEBC')
c recbuf dsply
c endif
C*------------------------
Csr endsr
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* This ends this program abnormally, and sends back an escape.
* message explaining the failure.
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P die B
D die PI
D peMsg 256A const
D SndPgmMsg PR ExtPgm('QMHSNDPM')
D MessageID 7A Const
D QualMsgF 20A Const
D MsgData 256A Const
D MsgDtaLen 10I 0 Const
D MsgType 10A Const
D CallStkEnt 10A Const
D CallStkCnt 10I 0 Const
D MessageKey 4A
D ErrorCode 32766A options(*varsize)
D dsEC DS
D dsECBytesP 1 4I 0 INZ(256)
D dsECBytesA 5 8I 0 INZ(0)
D dsECMsgID 9 15
D dsECReserv 16 16
D dsECMsgDta 17 256
D wwMsgLen S 10I 0
D wwTheKey S 4A
c eval wwMsgLen = %len(%trimr(peMsg))
c if wwMsgLen<1
c return
c endif
c callp SndPgmMsg('CPF9897': 'QCPFMSG *LIBL':
c peMsg: wwMsgLen: '*ESCAPE':
c '*PGMBDY': 1: wwTheKey: dsEC)
c return
P E
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* This procedure return call socket C API errno
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P errno B
D errno PI 10I 0
D p_errno S *
D wwreturn S 10I 0 based(p_errno)
C eval p_errno = @__errno
c return wwreturn
P E
File : QRPGLESRC
Member: SOCKETCLTR (Echo Client)
Type : RPGLE
Usage : CRTBNDRPG SOCKETCLTR
OS version: V4R1
H DFTACTGRP(*NO) ACTGRP(*NEW) BNDDIR('QC2LE')
H Debug
*-------------------------------------------------------------------
* prototype definitions
*-------------------------------------------------------------------
D @__errno PR * ExtProc('__errno')
D strerror PR * ExtProc('strerror')
D errnum 10I 0 value
D perror PR ExtProc('perror')
D comment * value options(*string)
D errno PR 10I 0
*-- Sleep --- Sleep function (delay job) ------------------------
* unsigned int sleep( unsigned int seconds );
D sleep Pr 10U 0 ExtProc('sleep')
D 10U 0 Value
* socket C API prototype definitions
*-------------------------------------------------------------------
D getservbyname PR * ExtProc('getservbyname')
D service_name * value options(*string)
D protocol_name * value options(*string)
D p_servent S *
D servent DS based(p_servent)
D s_name *
D s_aliases *
D s_port 10I 0
D s_proto *
D inet_addr PR 10U 0 ExtProc('inet_addr')
D address_str * value options(*string)
D INADDR_NONE C CONST(4294967295)
D inet_ntoa PR * ExtProc('inet_ntoa')
D internet_addr 10U 0 value
D p_hostent S *
D hostent DS Based(p_hostent)
D h_name *
D h_aliases *
D h_addrtype 10I 0
D h_length 10I 0
D h_addr_list *
D p_h_addr S * Based(h_addr_list)
D h_addr S 10U 0 Based(p_h_addr)
D gethostbyname PR * extproc('gethostbyname')
D host_name * value options(*string)
D socket PR 10I 0 ExtProc('socket')
D addr_family 10I 0 value
D type 10I 0 value
D protocol 10I 0 value
D AF_INET C CONST(2)
D SOCK_STREAM C CONST(1)
D IPPROTO_IP C CONST(0)
D bind PR 10I 0 ExtProc('bind')
D Sock_Desc 10I 0 Value
D p_Address * Value
D AddressLen 10I 0 Value
D connect PR 10I 0 ExtProc('connect')
D sock_desc 10I 0 value
D dest_addr * value
D addr_len 10I 0 value
D p_sockaddr S *
D sockaddr DS based(p_sockaddr)
D sa_family 5I 0
D sa_data 14A
D sockaddr_in DS based(p_sockaddr)
D sin_family 5I 0
D sin_port 5U 0
D sin_addr 10U 0
D sin_zero 8A
D send PR 10I 0 ExtProc('send')
D sock_desc 10I 0 value
D buffer * value
D buffer_len 10I 0 value
D flags 10I 0 value
D recv PR 10I 0 ExtProc('recv')
D sock_desc 10I 0 value
D buffer * value
D buffer_len 10I 0 value
D flags 10I 0 value
D close PR 10I 0 ExtProc('close')
D sock_desc 10I 0 value
D setsockopt PR 10I 0 ExtProc('setsockopt')
D SocketDesc 10I 0 Value
D Opt_Level 10I 0 Value
D Opt_Name 10I 0 Value
D Opt_Value * Value
D Opt_Len 10I 0 Value
D translate PR ExtPgm('QDCXLATE')
D length 5P 0 const
D data 32766A options(*varsize)
D table 10A const
D die PR
D peMsg 256A const
D* socket layer
D SOL_SOCKET C CONST(-1)
D* re-use local address
D SO_REUSEADDR C 55
D msg S 50A
D sock S 10I 0
D port S 5U 0
D addrlen S 10I 0
D ch S 1A
D host s 32A
D hostportc s 5A
D local s 32A
D localportc s 5A
D IPHost s 10U 0
D IPLocal s 10U 0
D p_bindto S *
D p_Connto S *
D RC S 10I 0
D Request S 50A
D ReqLen S 10I 0
D RecBuf S 50A
D RecLen S 10I 0
D on S 10I 0 inz(1)
D err S 10I 0
C*************************************************
C* The user will supply a hostname and file
C* name as parameters to our program...
C*************************************************
c *entry plist
c parm host
c parm hostportc
c parm local
c parm localportc
c eval *inlr = *on
c exsr SktCnn
c exsr TalkToSktSvr
C*************************************************
C* SOCKET CONNECTION
C*************************************************
C SktCnn BegSr
C*************************************************
C* Get the 32-bit network IP address for the host
C* & local that was supplied by the user:
C*************************************************
c eval IPHost = inet_addr(%trim(host))
c if IPHost = INADDR_NONE
c eval p_hostent = gethostbyname(%trim(host))
c if p_hostent = *NULL
c callp die('Unable to find that host!')
c return
c endif
c eval IPHost = h_addr
c endif
c If local <> *blanks
c eval IPLocal = inet_addr(%trim(local))
c if IPLocal= INADDR_NONE
c eval p_hostent = gethostbyname(%trim(local))
c if p_hostent = *NULL
c callp die('Unable to find that local!')
c return
c endif
c eval IPLocal = h_addr
c endif
c endif
C*************************************************
C* Create a socket
C*************************************************
c eval sock = socket(AF_INET: SOCK_STREAM:
c IPPROTO_IP)
c if sock < 0
c callp die('socket(): ' + %str(strerror(errno)))
c return
c endif
C*** Tell socket that we want to be able to re-use the server
C*** port without waiting for the MSL timeout:
c callp setsockopt(sock: SOL_SOCKET:
c SO_REUSEADDR: %addr(on): %size(on))
C if local <> *blanks And
C localportc <> *blanks
C* bind the socket to local port , of any IP address
C* Allocate some space for some socket addresses
c eval addrlen = %size(sockaddr_in)
c alloc addrlen p_bindto
c eval p_sockaddr = p_bindto
c move localportc port
c eval sin_family = AF_INET
c eval sin_addr = IPLocal
c eval sin_port = port
c eval sin_zero = *ALLx'00'
c if bind(sock: p_bindto: addrlen) < 0
c eval err = errno
c callp close(sock)
c callp die('bind(): ' + %str(strerror(err)))
c return
c endif
c endif
C*************************************************
C* Create a socket address structure that
C* describes the host & port we wanted to
C* connect to
C*************************************************
c eval addrlen = %size(sockaddr)
c alloc addrlen p_connto
c eval p_sockaddr = p_connto
c move hostportc port
c eval sin_family = AF_INET
c eval sin_addr = IPHost
c eval sin_port = port
c eval sin_zero = *ALLx'00'
C*************************************************
C* Connect to the requested host
C*************************************************
C if connect(sock: p_connto: addrlen) < 0
c eval err = errno
c callp close(sock)
c callp die('Connect(): ' + %str(strerror(err)))
c return
c endif
C EndSr
C*************************************************
C* TALK TO SOCKET SERVER
C*************************************************
C TalktoSktSvr BegSr
C*************************************************
C* Format a request and tralslate to ASCII and
C* send to socket server depend on your purpose
C*************************************************
C Dow *In99 = *Off
* once connect , receive socket server
* two welcome message
c N90 do 2
C exsr RecvResponse
c eval *In90 = *on
c enddo
* input anything you want
c clear request
c 'Input String'Dsply
c Dsply request
c eval reqlen = %len(%trim(request))
c If reqlen = 0
c iter
c EndIf
c If %SubSt(request : 1 : 4) = 'QUIT'
c eval *In99 = *On
c EndIf
c* eval request = 'Any data to send to socket server'
c callp Translate(reqlen: request: 'QTCPASC')
C*************************************************
c* Append ASCII X'0D0A' to request means end of
C* line and send the request to the socket server
C*************************************************
c eval request = %trim(request) + X'0D0A'
c eval reqlen = %len(%trim(request))
c eval rc = send(sock: %addr(request): reqlen:0)
c if rc < reqlen
c callp close(sock)
c callp die('Unable to send entire request!')
c return
c endif
c* 'sended' dsply
C exsr RecvResponse
C*************************************************
C* Get back the server's response
C*************************************************
C enddo
* get 'GoodBye' message
C exsr RecvResponse
C*************************************************
C* We're done, so close the socket.
C* do a dsply with input to pause the display
C* and then end the program
C*************************************************
c callp close(sock)
c dsply pause 1
c return
C EndSr
C*===============================================================
C* This subroutine receives what we send to server and
C* displays it on the screen using the DSPLY op-code
C*===============================================================
CSR RecvResponse begsr
C*------------------------
C*************************************************
C* Receive one line of text from the socket server.
C* note that "lines of text" vary in length,
C* but always end with the ASCII values for CR
C* and LF. CR = x'0D' and LF = x'0A'
C*
C* The easiest way for us to work with this data
C* is to receive it one byte at a time until we
C* get the LF character. Each time we receive
C* a byte, we add it to our receive buffer.
C*************************************************
c eval reclen = 0
c eval recbuf = *blanks
c dou reclen = 50 or ch = x'0A'
c eval rc = recv(sock: %addr(ch): 1: 0)
c if rc < 1
c leave
c endif
c if ch<>x'0D' and ch<>x'0A'
c eval reclen = reclen + 1
c eval %subst(recbuf:reclen:1) = ch
c endif
c enddo
C*************************************************
C* translate the line of text into EBCDIC
C* (to make it readable) and display it
C*************************************************
c if reclen > 0
c callp Translate(reclen: recbuf: 'QTCPEBC')
c endif
c recbuf dsply
C*------------------------
Csr endsr
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* This ends this program abnormally, and sends back an escape.
* message explaining the failure.
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P die B
D die PI
D peMsg 256A const
D SndPgmMsg PR ExtPgm('QMHSNDPM')
D MessageID 7A Const
D QualMsgF 20A Const
D MsgData 256A Const
D MsgDtaLen 10I 0 Const
D MsgType 10A Const
D CallStkEnt 10A Const
D CallStkCnt 10I 0 Const
D MessageKey 4A
D ErrorCode 32766A options(*varsize)
D dsEC DS
D dsECBytesP 1 4I 0 INZ(256)
D dsECBytesA 5 8I 0 INZ(0)
D dsECMsgID 9 15
D dsECReserv 16 16
D dsECMsgDta 17 256
D wwMsgLen S 10I 0
D wwTheKey S 4A
c eval wwMsgLen = %len(%trimr(peMsg))
c if wwMsgLen<1
c return
c endif
c callp SndPgmMsg('CPF9897': 'QCPFMSG *LIBL':
c peMsg: wwMsgLen: '*ESCAPE':
c '*PGMBDY': 1: wwTheKey: dsEC)
c return
P E
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* This procedure return call socket C API errno
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P errno B
D errno PI 10I 0
D p_errno S *
D wwreturn S 10I 0 based(p_errno)
C eval p_errno = @__errno
c return wwreturn
P E
執行方式:
1. 執行 Echo server
SBMJOB CMD(CALL SOCKETSVRR('your-as/400-ip' 'port')) JOB(SOCKETSVR)
or
SBMJOB CMD(CALL PGM(SOCKETSVRR) PARM('172.16.15.35' '04000')) JOB(SOCKETSR)
2. 執行 Echo client
CALL PGM(SOCKETcltR) PARM('your-as/400 ip' 'port' 'local-as/400 ip' 'local port')
or
CALL PGM(SOCKETCLTR) PARM('172.16.15.35' '04000' '172.16.15.35' '21000')
or
在 PC DOS 視窗上執行 telnet AS/400IPAddress PORT
telnet AS/400IP PORT
telnet 172.16.15.35 4000
本 Echo server 範例程式目前僅做 ASCII, EBCDIC 轉換,位支援 big5 中文轉換,
你可以使用 API iconv() 或 API QDCXLATE 轉換,或自行轉碼。 相關轉碼請參閱:
http://publib.boulder.ibm.com/iseries/v5r1/ic2924/info/apis/iconv.htm
http://publib.boulder.ibm.com/iseries/v5r1/ic2924/index.htm?info/apis/QDCXLATE.htm
A blog about IBM i (AS/400), MQ and other things developers or Admins need to know.
星期一, 11月 06, 2023
2003-08-06 TCPIP SOCKET RPG 程式範例(Echo server)
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言