HPlogo NetIPC 3000/XL Programmer's Reference Manual: HP 3000 MPE/iX Computer Systems > Chapter 4 NetIPC Examples

Example 1

» 

Technical documentation

Complete book in PDF
» Feedback

 » Table of Contents

 » Glossary

 » Index

In the first two programs (1A and 1B), the lengths of the data messages are not known. The sending side (Program 1A) includes the length of each message as the first two bytes of each message it sends. The receiving side (Program 1B) executes two IPCRECV loops for each message: first to receive the length and then to receive the data.

The first program (Program 1A):

  • looks up the call socket named RALPH located on node JANE and gets back a destination descriptor;

  • creates its own call socket;

  • sends a connection request to RALPH;

  • shuts down its call socket and its destination socket;

  • completes the connection;

  • executes a loop in which it:

    • reads a line of data;

    • stores the length (number of bytes) of the data in the first part of the message;

    • stores the data itself in the second part of the message;

    • sends the message on the connection, including the message length as the first two bytes of the message;

  • sends a "last message" which will be recognized by the receiving program as a termination request;

  • receives a "termination confirmation message" and shuts down the connection by releasing its VC socket.

The second program (Program 1B):

  • creates a call socket and names it RALPH;

  • waits to receive a connection request;

  • shuts down its call socket;

  • executes a loop in which it:

    • calls a procedure that receives a message by executing two IPCRECV loops (the first loop determines the incoming message length and the second loop receives data until all the pieces of the message have been received);

    • prints the message which was received;

  • receives a "last message" termination request;

  • sends a "termination confirmation message" in response to the termination request;

  • receives a result parameter value of 64 ("REMOTE ABORTED CONNECTION") in response to a receive request;

  • releases its VC socket.

Program 1A

$standard_level 'HP3000', uslinit$
program connection_example1 (input,output);
 
const
     maxdata = 2000;
     maxmsg = maxdata + 2;
     maxname = 20;
     maxloc = 20;
type
     smallint = -32768..32767;
    datatype = record;
       len : smallint;
       msg : packed array[1..maxdata] of char;
    end;
timeval type = 
    record case boolean of
       true  : (int   : smallint);
       false : (chars : packed array [1..30] of char);
    end;
    nametype = packed array[1..maxname] of char;
    loctype = packed array[1..maxloc] of char;
var  calldesc       :     integer;   {2-word integer}
       vcdesc       :     integer;
       protocol  :     integer;
       socket_kind  :     integer;
       dest         :     integer;
       result       :     integer;
       data         :     datatype;
       name         :     nametype;
       location  :     loctype;
       y_len        :     integer;
       y_data       :     char;
       num_msgs  :     integer;
       strdata      :     string[maxdata];
       i            :     integer;
       timeval  :     timeval type;
procedure terminate;      intrinsic;
{NetIPC intrinsic declarations}
procedure   ipccreate;    intrinsic;
procedure   ipclookup;    intrinsic;
procedure   ipcconnect;   intrinsic;
procedure   ipcrecv;      intrinsic;
procedure   ipcsend;      intrinsic;
procedure   ipcshutdown   intrinsic;
procedure   ipcerrmsg;    intrinsic;
procedure   ipccontrol;   intrinsic; 
 
{error handling procedure}
 
procedure leave(result: integer);
     var  msg: string[80];
          i, len, newresult: integer;
begin 
     ipcerrmsg(result, msg, len, newresult);
     if newresult = 0 then
       begin
          setstrlen(msg, len);
          writeln(msg);           {print error message}
       end
     else
     writeln('IpcErrMsg result is ', newresult:1);
terminate;
end; 
 
{main of NetIPC Program 1}
 
begin 
{ look up the call socket RALPH located on node JANE }
name:= 'RALPH';
location:= 'JANE';
ipclookup( name, 5, location, 4, , dest, protocol, socket_kind, result);
     if result <> 0 then leave(result); {failed}
{ create a call socket; then initiate and complete connection to destination socket}
 
ipccreate(socket_kind, protocol, , , calldesc, result);
     if result <> 0 then leave(result); {failed}
ipcconnect(calldesc, dest, , , vcdesc, result);  {initiate connection}
     if result <> 0 then leave(result); {failed}
timeval.int:=0;
ipccontrol(vcdesc, 3, timeval.chars, 2, , , result);
     if result <> 0 then leave(result);
ipcshutdown(calldesc);
ipcshutdown(dest);
ipcrecv(vcdesc, , , , , result); {complete connection}
if result <> 0 then leave(result);     {failed}
{ prompt for messages and send them }
writeln('Enter "//" to terminate the program.');
setstrlen(strdata, 0);
while strdata <> '//' do
     begin
     prompt('Message? ');
     readln(strdata);             {read message}
     data.len := strlen(strdata); {store message length}      strmove(data.len, strdata, 1, data.msg, 1);        {store message}
     ipcsend(vcdesc, data, data.len+2, , ,result)  {send message with length 
                                                   as first 2 bytes}
   if result <>  0 then leave(result); {failed}
end;
 
{connection shutdown procedure}
 
data.len := 4;
data.msg := 'END?'                       { termination request}
ipcsend(vcdesc, data, 6, , , result);
      writeln('END sent');
if result <> 0 then leave(result);
      y_len := 1;
ipcrecv(vcdesc, y_data, y_len, , , result);   {receive 'Y' confirmation}
if (y_data = 'Y') then writeln('Y received');
if (y_data = 'Y') and (result = 0) then
           ipcshutdown(vcdesc) 
else
      begin
        writeln('Warning: shutdown not confirmed or result  0');
        leave(result);
     end;
end.

Program 1B

$standard_level 'HP3000', uslinit$
program connection_example2 (output);
 
const
    maxdata = 2000;
    maxname = 20;
type
     smallint = -32768..32767;
     datatype = packed array [1..maxdata] of char;
timeval type =
     record case boolean of
     true  : (int   : smallint);
           false : (chars : packed array [1..30] of char);
     end;
           nametype = packed array [1..maxname] of char;
var        calldesc    :     integer;          {2-word integer}
           vcdesc      :     integer;
           dlen        :     integer;
           result      :     integer;
           data        :     datatype;
           name        :     nametype;
           len         :     smallint;
           datastr     :     string[maxdata];
           timeval     :     timeval type;
procedure terminate;    intrinsic;  
 
{NetIPC intrinsic declarations}
 
procedure    ipccreate;        intrinsic;
procedure    ipcname;          intrinsic;
procedure    iprecvcn;         intrinsic;
procedure    ipcrecv;          intrinsic;
procedure    ipcsend;          intrinsic;
procedure    ipcshutdown;      intrinsic;
procedure    ipcerrmsg;        intrinsic;
procedure    ipccontrol;       intrinsic;
{error handling procedure}
procedure leave(result : integer);
     var msg: string[80];
          i, len, newresult: integer;
begin
     ipcerrmsg(result, msg, len, newresult);
     if newresult = 0 then
          begin    setstrlen(msg, len);
          writeln(msg);                        {print error message}
     end
     else
     writeln('IpcErrMsg result is ', newresult:1);
     terminate;
end;
{ The following procedure receives one message which was sent via an ipcsend call. It assumes that the length (number of bytes) of the message was sent as the first two bytes of data and that the length value does not include those two bytes. }
procedure receive ( connection : integer;
                     var       rbfr :      datatype;
                     var       rlen :      smallint;
                     var       errorcode : integer    ) ;
const     head_len = 2;
type      length_buffer_type = packed array[1..2] of char;
          header_len_type = record 
                 case integer of
                 0: ( word: smallint );
                 1: ( byte: length_buffer_type);
                 end;
var  i, j                   :integer;
           dlen             :integer;
           header_len  :header_len_type;
           tempbfr         :datatype;
 
begin      { procedure receive }
i:=0;
errorcode := 0;
while (i <> head_len) and (errorcode = 0) do { get length of message }
     begin     
     dlen := head_len - i;
     ipcrecv( connection, tempbfr, dlen, , , errorcode );
     if errorcode = 0 <F100P12M>
        then strmove(dlen, tempbfr, 1, header_len.byte, i+1);
          i := i + dlen;
     end;
if errorcode = 0 then
     begin
     rlen := header_len.word;
     i := 0;
     while (i <> rlen) and (errorcode = 0) do { get the message }
         begin
         dlen := header_len.word - i;
         ipcrecv ( connection, tempbfr, dlen, , ,errorcode );
         if errorcode = 0
           then strmove(dlen, tempbfr, 1, rbfr, i+1);
           i := i + dlen;
         end;
     end 
else
     rlen := 0;
end;
{ procedure receive }
{main of NetIPC Program 2}
 
begin
 
{create a call socket and name it}
ipccreate(3, 4, , , calldesc, result);
if result <> 0 then
     leave(result);                  {failed}
name := 'RALPH';
ipcname(calldesc, name, 5, result );
if result <> 0 then
     leave(result);                  {failed}
{wait for a connection request}
timeval.int:=0;
ipccontrol(calldesc, 3, timeval.chars, 2, , , result);
 
ipcrecvcn(calldesc, vcdesc, , , result);
if result <> 0 then
     leave(result);                  {failed}
ipcshutdown(calldesc);
 
{wait for a message on the connection and print message received}
 
repeat
     begin
     receive (vcdesc, data, len, result);
     if result <> 0 then leave(result);
     setstrlen(datastr, len);
     strmove(len, data, 1, datastr, 1);
     if datastr <> 'END?' then writeln (datastr);       {print data received}
     end
until datastr = 'END?';
 
{connection shutdown procedure}
 
if datastr = 'END?' then writeln('END received');
data := 'Y';
ipcsend( vcdesc, data, 1, , , result ); 												{confirmation message}
writeln('Y sent');
if result <> 0 then leave(result);
receive(vcdesc, data, len, result );
if result = 64 then
     ipcshutdown(vcdesc) 
else
     leave(result );
end.
Feedback to webmaster