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