7.10. Trying the "generic server" out

If you haven't already done so, compile the "generic server" example like this:

CRTBNDRPG SVREX7L SRCFILE(SOCKTUT/QRPGLESRC) DBGVIEW(*LIST)

CRTBNDRPG SVREX7I SRCFILE(SOCKTUT/QRPGLESRC) DBGVIEW(*LIST)

CRTBNDRPG TESTPGM SRCFILE(SOCKTUT/QRPGLESRC) DBGVIEW(*LIST)

Then start it up, like so:

SBMJOB CMD(CALL SVREX7L) JOBQ(QSYSNOMAX) JOB(LISTENER)

Try it out by telnetting from your PC:

telnet as400 4000

It'll ask for your user-id, and password. After you've typed both, it'll set your user profile to the one that you've typed it.

Note: Unless SVREX7L was submitted by a user with *ALLOBJ authority, it will only be able to set the user profile to the same profile that it's running under. This is a security safeguard on the AS/400 that prevents programmers from writing programs that would give them more access than they are allowed to have. The solution, of course, would be to run SVREX7L from a job with *ALLOBJ authority, so that it can handle sign-ons for any user.

Once it has set the user profile, it'll ask you for a program to call. You can qualify your program name with a library if you like. To try my demonstration program, you could type SOCKTUT/TESTPGM

You'll notice that each response the server program sends to the telnet client is prefixed by a 3-digit number. This is to make it easy to write a client program that interfaces with the server. The first 3 digits are always a number, so if the client wanted to display the human-readable portion, it could do a simple substring starting in position 5 to remove the message number. The message number can be used to discern exactly what the server is expecting. Plus, any number starting with a '1' is a positive response, any number starting with a '9' is a negative (error) response.

The TESTPGM program will say 'hello' & 'goodbye' just as our other simple server programs have done. Not particularly practical, but it's always good to start simple.

Here's another example of a program you could call. This one asks for the name of a source file, and a member. It then sends back the member's contents. Each source line starts with an extra '.', which a client program would normally remove. This is useful, as it allows us to tell the difference between a line of source code and a server's response message.

    File: SOCKTUT/QRPGLESRC, Member: GETSRC
         H DFTACTGRP(*NO) ACTGRP(*NEW)
         H BNDDIR('SOCKTUT/SOCKUTIL') BNDDIR('QC2LE')
    
         FSOURCE    IF   F  252        DISK    USROPN INFDS(dsSrc)
    
          *** header files for calling service programs & APIs
    
         D/copy socktut/qrpglesrc,socket_h
         D/copy socktut/qrpglesrc,sockutil_h
    
         D Cmd             PR                  ExtPgm('QCMDEXC')
         D   command                    200A   const
         D   length                      15P 5 const
    
         D dsSrc           DS
         D   dsSrcRLen           125    126I 0
    
         D lower           C                   'abcdefghijklmnopqrstuvwxyz'
         D upper           C                   'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    
         D sock            S             10I 0
         D user            S             10A
         D file            S             21A
         D mbr             S             10A
         D reclen          S              5I 0
    
         ISOURCE    NS
         I                                 13  252  SrcDta
    
         c     *entry        plist
         c                   parm                    sock
         c                   parm                    user
    
         c                   eval      *inlr = *on
    
         c                   callp     WrLine(sock: '110 Name of source file?')
         c                   if        RdLine(sock: %addr(file): 21: *On) < 0
         c                   return
         c                   endif
    
         c                   callp     WrLine(sock: '111 Name of member?')
         c                   if        RdLine(sock: %addr(mbr): 21: *On) < 0
         c                   return
         c                   endif
    
         c     lower:upper   xlate     file          file
         c     lower:upper   xlate     mbr           mbr
    
         c                   callp(e)  cmd('OVRDBF FILE(SOURCE) ' +
         c                                        'TOFILE('+%trim(file)+') ' +
         c                                        'MBR(' +%trim(mbr)+ ')': 200)
         c                   if        %error
         c                   callp     WrLine(sock: '910 Error calling OVRDBF')
         c                   return
         c                   endif
    
         c                   open(e)   SOURCE
         c                   if        %error
         c                   callp     WrLine(sock: '911 Unable to open file!')
         c                   callp     Cmd('DLTOVR FILE(SOURCE)': 200)
         c                   return
         c                   endif
    
         c                   eval      reclen = dsSrcRLen - 12
    
         c                   read      SOURCE
         c                   dow       not %eof(SOURCE)
         c                   if        WrLine(sock:
         c                                    '.' + %subst(SrcDta:1:reclen)) < 0
         c                   leave
         c                   endif
         c                   read      SOURCE
         c                   enddo
    
         c                   callp     WrLine(sock: '112 Download successful!')
    
         c                   close     SOURCE
         c                   callp     Cmd('DLTOVR FILE(SOURCE)': 200)
         c                   return
     


Compile it by typing:

CRTBNDRPG GETSRC SRCFILE(SOCKTUT/QRPGLESRC) DBGVIEW(*LIST)

Now use your PC to telnet to the AS/400's port 4000 again. Type in your user name and pasword. When it asks for the program, type socktut/getsrc. For source file, you might type something like SOCKTUT/QRPGLESRC for source member, maybe type TESTPGM

See how easy it is, using this example server program to write your own TCP servers? Just think, by writing your own program (perhaps somewhat similar to GETSRC) and by writing a GUI client program, you could write a client/server application using native RPG database access!

Whew. I think we've covered server programs well enough for now. Time to try something new...