|
On 02/05/99 05:45:24 AM Jocke Berggren wrote:
>Anyone have experience in RPG-ILE sockets programming ?
I'm working on a prototype client right now. The only thing I don't have
is the ASCII/EBCDIC translation and error handling.
>The OS400 Sockets Programming V4R2 says I need to compile
>a server module called RPGSOCKET coded in ILE C, but we don't
>have any c compiler. Can I find the server module anywhere else
>compiled and ready to run ?
I could send it to you if you wish, but you don't actually need it. I've
been doing all the work in RPG IV (not ILE). It's not that hard converting
C code to RPG once you understand the way the structures nest. The only
"gotcha" is that you need to remember to terminate your strings with x'00
like C does. Here's my RPG version of the C client:
H Debug Copyright('C 1999 CommSoft, Albany, NY')
* DFTACTGRP(*NO) ACTGRP(QILE) DBGVIEW(*LIST) TGTRLS(V3R7M0)
* This is meant to work with the C example server taken
* from the socket programming guide, called CCLI in lib BUCK
D buffer S 1A Dim(250) Inz
D BufferLength S 10I 0 Inz(%size(buffer:*All))
D SERVPORT S 10I 0 Inz(3005)
D SERVERParm S 255A Inz('machine.company.com')
D sd S 10I 0 Inz
D rc S 10I 0 Inz
D cnt S 10I 0 Inz
D length S 10I 0 Inz(%size(rc))
D addrlen S 10I 0 Inz
D totalcnt S 10I 0 Inz
D on S 10I 0 Inz
D temp S 1A Inz
D read_fd S 10I 0 Dim(7) Inz
D h_errno S 10I 0 Based(h_errnoP)
D server S * Inz
D hostent_dataP S * Inz
D h_errnoP S * Inz
* Address families
D AF_UNIX S 10I 0 Inz(1)
D AF_INET S 10I 0 Inz(2)
* Socket types
D SOCK_STREAM S 10I 0 Inz(1)
D SOCK_DGRAM S 10I 0 Inz(2)
D SOCK_RAW S 10I 0 Inz(3)
D SOCK_SEQPACKET S 10I 0 Inz(5)
* Socket level options
D SO_BROADCAST S 10I 0 Inz(5)
D SO_DEBUG S 10I 0 Inz(10)
D SO_DONTROUTE S 10I 0 Inz(15)
D SO_ERROR S 10I 0 Inz(20)
D SO_KEEPALIVE S 10I 0 Inz(25)
D SO_LINGER S 10I 0 Inz(30)
D SO_OOBINLINE S 10I 0 Inz(35)
D SO_RCVBUF S 10I 0 Inz(40)
D SO_RCVLOWAT S 10I 0 Inz(45)
D SO_RCVTIMEO S 10I 0 Inz(50)
D SO_REUSEADDR S 10I 0 Inz(55)
D SO_SNDBUF S 10I 0 Inz(60)
D SO_SNDLOWAT S 10I 0 Inz(65)
D SO_SNDTIMEO S 10I 0 Inz(70)
D SO_TYPE S 10I 0 Inz(75)
D SO_USELOOPBACK S 10I 0 Inz(80)
* Internet address specifications
D INADDR_ANY S 10I 0 Inz(0)
D INADDR_BROADCA S 10I 0 Inz(-1)
D INADDR_LOOPBAC S 10I 0 Inz(2130706433)
D INADDR_NONE S 10I 0 Inz(-1)
* Returned h_errno values
D HOST_NOT_FOUND S 10I 0 Inz(5)
D NO_DATA S 10I 0 Inz(10)
D NO_ADDRESS S 10I 0 Inz(10)
D NO_RECOVERY S 10I 0 Inz(15)
D TRY_AGAIN S 10I 0 Inz(20)
* Misc
D SOL_SOCKET S 10I 0 Inz(-1)
D SOMAXCONN S 10I 0 Inz(512)
D hostp S * Inz
* Socket address
D serveraddr DS
D sin_family 5I 0
D sin_port 5U 0
D sin_addr 10U 0
D sin_zero 8
*
D timeout DS
D tv_sec 10I 0 Inz(10)
D tv_usec 10I 0 Inz(0)
* Host entry returned pointers
D hostent DS Align Based(hostp)
D h_namePtr *
D h_aliasesPtr *
D h_addrtype 10I 0
D h_length 10I 0
D h_addrlistPtr *
* Host entry data
D hostent_data DS Align Based(hostent_dataP)
D h_name 256A
D h_aliasesArrP * Dim(65)
D h_aliasesArr 256A Dim(64)
D h_addrArrP * Dim(101)
D h_addrArr 10U 0 Dim(100)
D open_flag 10I 0
D f0 *
D filep0 260A
D reserved_0 150A
D f1 *
D filep1 260A
D reserved_1 150A
D f2 *
D filep2 260A
D reserved_2 150A
* Create a socket
* #include <sys/types.h>
* #include <sys/socket.h>
*
* int socket(int address_family,
* int type,
* int protocol)
*
D socket PR Extproc('socket') Like(rc)
D 10I 0 Value
D 10I 0 Value
D 10I 0 Value
* Set socket options
* #include <sys/types.h>
* #include <sys/socket.h>
*
* int setsockopt(int socket_descriptor,
* int level,
* int option_name,
* char *option_value,
* int option_length)
*
D setsockopt PR Extproc('setsockopt') Like(rc)
D 10I 0 Value
D 10I 0 Value
D 10I 0 Value
D * Value
D 10I 0 Value
* Bind to a socket
* #include <sys/types.h>
* #include <sys/socket.h>
*
* int bind(int socket_descriptor,
* struct sockaddr *local_address,
* int address_length)
*
D bind PR Extproc('bind') Like(rc)
D 10I 0 Value
D * Value
D 10I 0 Value
* Get host address from name
* #include <netdb.h>
*
* struct hostent *gethostbyname(char *host_name)
*
* struct hostent {
* char *h_name;
* char **h_aliases;
* int h_addrtype;
* int h_length;
* char **h_addr_list;
* };
*
D gethostbyname PR * Extproc('gethostbyname')
D * Value
* Connect to the server
* #include <sys/types.h>
* #include <sys/socket.h>
*
* int connect(int socket_descriptor,
* struct sockaddr *destination_address,
* int address_length)
*
D connect PR Extproc('connect') Like(rc)
D 10I 0 Value
D * Value
D 10I 0 Value
* Write data to the server
* #include <unistd.h>
*
* ssize_t write(int descriptor,
* const void *buffer,
* size_t buffer_length)
*
D write PR Extproc('write') Like(rc)
D 10I 0 Value
D * Value
D 10U 0 Value
* Read data from the server
* ssize_t read(int descriptor,
* void *buffer,
* size_t buffer_length)
*
D read PR Extproc('read') Like(rc)
D 10I 0 Value
D * Value
D 10U 0 Value
* Close a socket
*
* #include <unistd.h>
*
* int close(int descriptor)
*
D close PR Extproc('close')
D 10I 0 Value
* Report errors
* #include <netdb.h>
*
* QBFC_EXTERN int * __h_errno(void);
*
*
D Get_h_errno PR * Extproc('__h_errno')
* ==========================================================
* Setup
* ==========================================================
* Get a socket descriptor
C Eval sd=socket(AF_INET: SOCK_STREAM: 0)
C If sd<0
C Dump
C Eval *InLR=*On
C Return
C EndIf
* Get the host address if given the server name
C Eval serveraddr=*allx'00'
C Eval sin_family=AF_INET
C Eval sin_port=SERVPORT
C Eval SERVERParm=%trim(SERVERParm) + x'00'
C Eval server=%addr(SERVERParm)
C Eval hostp=gethostbyname(server)
C If hostp=*Null
C Dump
C CallP close(sd)
C Eval *InLR=*On
C Return
C EndIf
* Set the pointer to the host entry data structure
C Eval hostent_dataP=h_namePtr
* Copy the IP address from the host entry structure into
* the server address
C Eval sin_addr=h_addrArr(1)
* Connect to the server
C Eval rc=connect(sd:
C %addr(serveraddr):
C %size(serveraddr))
C If rc < 0
C CallP close(sd)
C Dump
C Eval *InLR=*On
C Return
C EndIf
* ==========================================================
* Write to the server
C Eval buffer=*all'a'
C Eval rc=write(sd: %addr(buffer):
C %size(buffer:*All))
C If rc < 0
C CallP close(sd)
C Dump
C Eval *InLR=*On
C Return
C EndIf
C 'post write()'Dump
* ==========================================================
* Read data from the server one chunk at a time
C Eval buffer=*blank
C Eval totalcnt=0
C DoW totalcnt<BufferLength
C Eval rc=read(sd: %addr(buffer(totalcnt+1)):
C BufferLength-totalcnt)
C If rc < 0
C Eval h_errnoP=Get_h_errno
C CallP close(sd)
C Dump
C Eval *InLR=*On
C Return
C EndIf
C If rc = 0
C CallP close(sd)
C Dump
C Eval *InLR=*On
C Return
C EndIf
C Eval totalcnt=totalcnt+rc
C EndDo
C 'post read()' Dump
* ==========================================================
* Cleanup
C CallP close(sd)
C Eval *InLR=*On
C Return
Please note that this is a very early prototype stolen directly from the
manual with the exception of error handling and code translation; it hasn't
been debugged to my satisfaction and error handling is nil. In addition,
the code isn't too attractive. It *did* successfully communicate with the
C socket server on the same AS/400. Feel free to jump in with a critique
-- I'm definitely in the learning stages here.
Buck Calabro
CommSoft, Albany, NY
mailto:mcalabro@commsoft.net
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* This is the RPG/400 Discussion Mailing List! To submit a new *
* message, send your mail to "RPG400-L@midrange.com". To unsubscribe *
* from this list send email to MAJORDOMO@midrange.com and specify *
* 'unsubscribe RPG400-L' in the body of your message. Questions should *
* be directed to the list owner / operator: david@midrange.com *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2025 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.