{$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.