EchoServerImpl.mesa - implementation module for the Pilot OISCP Echo Server
Copyright © 1985 by Xerox Corporation. All rights reserved.
Garlick on: January 23, 1981 5:43 PM
DIRECTORY
BufferDefs USING [OisBuffer],
CommunicationInternal USING [],
CommFlags USING [doStats],
Echo USING [echoRequest, echoResponse],
OISCP USING [ReturnFreeOisBuffer, unknownNetID],
OISCPConstants USING [echoerSocket],
Router USING [FindMyHostID],
Socket USING [Abort, ChannelAborted, Create, Delete, GetPacket, PutPacket, SetWaitTime, TimeOut, TransferStatus, WaitTime],
SocketInternal USING [SocketObject],
NSAddress USING [NetworkAddress],
StatsDefs USING [StatIncr, StatBump];
EchoServerImpl: PROGRAM
IMPORTS OISCP, Router, Socket, StatsDefs
EXPORTS CommunicationInternal, Echo, Socket
SHARES BufferDefs = BEGIN
EXPORTED TYPE(s)
NetworkAddress: PUBLIC TYPE = NSAddress.NetworkAddress;
ChannelHandle: TYPE = REF ChannelObject;
ChannelObject: PUBLIC TYPE = SocketInternal.SocketObject;
global constants to all
nBuffers: CARDINAL = 2;
global variables to all
cH: ChannelHandle;
localAddr: NetworkAddress;
echoServerFork: PROCESS;
echoerTimeout: Socket.WaitTime = 7777777777B; -- in msec (about 10 days)
Cold Procedures
This procedure creates an echo server.
CreateServer: PUBLIC PROCEDURE =
BEGIN
localAddr ←
[net: OISCP.unknownNetID, host: Router.FindMyHostID[],
socket: OISCPConstants.echoerSocket];
cH ← Socket.Create[localAddr, 0, nBuffers, 0, FALSE];
no send or reserve buffers, 2 receive buffers, FALSE -> share buffers from system pool.
echoServerFork ← FORK EchoServer[];
END; -- CreateServer
This procedure deletes the echo server.
DeleteServer: PUBLIC PROCEDURE =
BEGIN Socket.Abort[cH]; JOIN echoServerFork; Socket.Delete[cH]; END;
DeleteListener
Hot Procedures
This procedure echos Echo protocol packets back to the remote end.
EchoServer: PROCEDURE =
BEGIN
buf: BufferDefs.OisBuffer;
Socket.SetWaitTime[cH, echoerTimeout];
init the PhysicalRecords and start the gets
DO
wait for an echo request packet
buf ← NIL;
buf ← Socket.GetPacket[
cH ! Socket.TimeOut => RETRY; Socket.ChannelAborted => EXIT];
b.status can be one of aborted or goodCompletion
SELECT LOOPHOLE[buf.status, Socket.TransferStatus] FROM
goodCompletion =>
BEGIN
IF buf.ois.transCntlAndPktTp.packetType = echo THEN
BEGIN
firstWord: LONG POINTER TO WORD ← @buf.ois.oisWords[0];
examine this packet
IF firstWord^ = Echo.echoRequest THEN
BEGIN
good packet, echo it
buf.ois.destination ← buf.ois.source;
firstWord^ ← Echo.echoResponse;
IF CommFlags.doStats THEN StatsDefs.StatIncr[packetsEchoed];
IF CommFlags.doStats THEN
StatsDefs.StatBump[bytesEchoed, buf.ois.pktLength];
Socket.PutPacket[cH, buf ! Socket.ChannelAborted =>
BEGIN
OISCP.ReturnFreeOisBuffer[buf];
EXIT;
END];
LOOP;
END
ELSE IF CommFlags.doStats THEN StatsDefs.StatIncr[packetsBadEchoed]
END
ELSE IF CommFlags.doStats THEN StatsDefs.StatIncr[packetsBadEchoed];
END; -- end goodCompletion
aborted => EXIT;
ENDCASE => NULL;
OISCP.ReturnFreeOisBuffer[buf];
ENDLOOP;
we got here via an abort or error; now clean up this world.
Socket.Abort[cH];
END; -- EchoServer
END.