|
» |
|
|
|
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: 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;
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.
|
|