× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.


  • Subject: Re: Sockets programming in RPG-ILE - LONG CODE SAMPLE
  • From: Buck Calabro/commsoft<mcalabro@xxxxxxxxxxxx>
  • Date: Tue, 9 Feb 1999 13:15:26 -0500

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 thread ...

Follow-Ups:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 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.