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