HP 3000 Manuals

Example 1 [ Net IPC 3000/XL Programmer's Reference Manual ] MPE/iX 5.0 Documentation


Net IPC 3000/XL Programmer's Reference Manual

Example 1 

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
        IPCRECVloops (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     ipcrecvcn;         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
                  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.



MPE/iX 5.0 Documentation