146 lines
3.9 KiB
Plaintext
146 lines
3.9 KiB
Plaintext
{$X+,V-,B-}
|
|
program RecHello3;
|
|
|
|
{ Simple IPX demonstration program, that uses one receive ESR.
|
|
|
|
Run this program on 1 workstation, run S_HELLO or S1_HELLO on another.
|
|
S_HELLO will send "hello world" messages,
|
|
this workstation will receive them. }
|
|
|
|
{ This program consists of two concurrent processes:
|
|
|
|
1. (background) An ESR that fills a global receive buffer with
|
|
incoming packets. Only when the buffer is full
|
|
will packets be discarded.
|
|
|
|
2. (foreground) A process that performs its regular task. Whenever
|
|
there is time, the process will process the
|
|
received packets. }
|
|
|
|
uses crt,nwMisc,nwIPX;
|
|
|
|
CONST IOSocket=$5678;
|
|
|
|
Var ReceiveEcb :Tecb;
|
|
IpxHdr :TipxHeader;
|
|
socket :word;
|
|
buf :array[1..546] of byte;
|
|
t :byte;
|
|
ReceivedBufLen:word;
|
|
|
|
ReceivedMsg:array[1..100] of record
|
|
InUse:Boolean;
|
|
Message:string[25];
|
|
end;
|
|
|
|
EsrBufInd :Byte; { used by ESR }
|
|
|
|
NewStack:array[1..1024] of word; { !! used by ESR }
|
|
StackBottom:word; { !! used by ESR }
|
|
|
|
|
|
{$F+}
|
|
Procedure ListenESRhandler(Var p:Tpecb);
|
|
begin
|
|
{ look for an empty spot in the global buffer }
|
|
EsrBufInd:=1;
|
|
while (EsrBufInd<=100) and ReceivedMsg[EsrBufInd].Inuse
|
|
do inc(EsrBufInd);
|
|
IF EsrBufInd<=100
|
|
then begin
|
|
{ empty place found. Insert msg }
|
|
with ReceivedMsg[EsrBufInd]
|
|
do begin
|
|
Message[0]:=chr(p^.fragment[2].size);
|
|
if Message[0]>#25 then Message[0]:=#25;
|
|
move(p^.fragment[2].address^,Message[1],ord(Message[0]));
|
|
InUse:=True;
|
|
end;
|
|
end
|
|
else ; { entire buffer is filled => discard packet }
|
|
{ Setup to listen for next incoming packet }
|
|
IPXListenForPacket(ReceiveECB);
|
|
end;
|
|
{$F-}
|
|
|
|
{$F+}
|
|
Procedure ListenESR; assembler;
|
|
asm { ES:SI are the only valid registers when entering this procedure ! }
|
|
mov dx, seg stackbottom
|
|
mov ds, dx
|
|
|
|
mov dx,ss { setup of a new local stack }
|
|
mov bx,sp { ss:sp copied to dx:bx}
|
|
mov ax,ds
|
|
mov ss,ax
|
|
mov sp,offset stackbottom
|
|
push dx { push old ss:sp on new stack }
|
|
push bx
|
|
|
|
push es { push es:si on stack as local vars }
|
|
push si
|
|
mov di,sp
|
|
|
|
push ss { push address of local ptr on stack }
|
|
push di
|
|
CALL ListenEsrHandler
|
|
|
|
add sp,4 { skip stack ptr-copy }
|
|
pop bx { restore ss:sp from new stack }
|
|
pop dx
|
|
mov sp,bx
|
|
mov ss,dx
|
|
end;
|
|
{$F-}
|
|
|
|
|
|
begin
|
|
IF NOT IpxInitialize
|
|
then begin
|
|
writeln('Ipx needs to be installed.');
|
|
halt(1);
|
|
end;
|
|
socket:=IOSocket;
|
|
IF NOT IPXopenSocket(Socket,SHORT_LIVED_SOCKET)
|
|
then begin
|
|
writeln('IPXopenSocket returned error# ',nwIPX.result);
|
|
halt(1);
|
|
end;
|
|
|
|
FillChar(buf,546,#0);
|
|
|
|
{ Setup ECB and IPX header }
|
|
IPXsetupListenECB(Addr(ListenESR),IOsocket,@buf,546,
|
|
IpxHdr,ReceiveEcb);
|
|
|
|
IPXListenForPacket(ReceiveECB);
|
|
|
|
writeln('ESR will start filling a global buffer with packets received.');
|
|
writeln('Starting foreground process...');
|
|
writeln;
|
|
writeln('Foreground process just writes a ''dot'' to the screen every second.');
|
|
writeln('When a key is pressed, this process is terminated and the received');
|
|
writeln('packets are shown.');
|
|
|
|
REPEAT
|
|
IPXrelinquishControl;
|
|
delay(1000);
|
|
write('.');
|
|
UNTIL KeyPressed;
|
|
|
|
writeln;
|
|
writeln('Dumping global receive buffer -- filled by background process.');
|
|
|
|
for t:=1 to 100
|
|
do if ReceivedMsg[t].Inuse
|
|
then begin
|
|
writeln(ReceivedMsg[t].Message);
|
|
ReceivedMsg[t].Inuse:=False; { give entry in buffer free }
|
|
end;
|
|
{ You may also choose to process just 1 entry in the received buffer.
|
|
Set Inuse to False after processing, so the ESR can fill it again }
|
|
|
|
IF NOT IPXcloseSocket(IOsocket)
|
|
then writeln('IPXcloseSocket returned error# ',nwIPX.result);
|
|
|
|
end. |