PROGRAM ServerSim; {Programmer: Gregory A. Perkins CS 65 Due: 20 November 1996} {This program simulates an internet server processing outgoing messages and reports the maximum wait time for messages to be processed} USES cs65; {contains the random functions and IntToStr functions} {Declaration module} CONST Num = 5600; {number of elements in array - used mainly for testing phase} TYPE WaitArray = ARRAY[1..Num] OF REAL; {Holds value of max wait time for each rate} CONST NumRot = 50; {number of run times per rate} CONST Inc = 1; {increment value of rate} VAR WaitY : WaitArray; VAR MessFile, MessMax : LONGINT; VAR Tick, Packet, Rate, Rotation, Count : INTEGER; VAR Wait, WaitSum, WaitAve : REAL; VAR PlotX, PlotY : INTEGER; VAR WaitDisplay, TempStr : STRING; {Subprogram module} FUNCTION Message(R : INTEGER) : INTEGER; VAR Event : REAL; BEGIN Message := 0; Event := Random; IF (Event <= (R / 111111.111111)) THEN Message := 50 * (RandomInt(39) + 1) {average of 1000 characters/message} ELSE Message := 0; END; PROCEDURE Server(VAR PSize : INTEGER; VAR MSize : LONGINT); BEGIN IF PSize = 1000 THEN PSize := 0; PSize := PSize + 50; MSize := MSize - 50; END; {---------------------- STOLEN FROM BOWLING PROGRAM ------------------------------} FUNCTION DigitToChar(D : INTEGER) : Char; {Converts a digit to a character (e.g. 3 becomes '3'). Numbers other than a single digit become an 'X' } BEGIN IF (D > 9) OR (D < 0) THEN DigitToChar := 'X' ELSE DigitToChar := CHR(D+48); END; PROCEDURE IntToStr( X, Width:INTEGER; VAR Result:STRING); { Convert an Integer into a String suitable for outTextXY. If X has fewer than Width digits, it is padded on the left with blanks. If X has more than Width digits, Result will be whatever length is required to store the digits} VAR Length,Digit, i, Index : INTEGER; tempStr : STRING; BEGIN {IntToStr} {First decode digits into tempStr} Length := 0; IF X = 0 THEN BEGIN Length := 1; tempStr := "0"; END ELSE WHILE X > 0 DO BEGIN Length := Length + 1; Digit := X MOD 10; TempStr[Length] := DigitToChar(Digit); X := X DIV 10; END; {Pad to appropriate width} WHILE Length < Width DO BEGIN Length := Length + 1; TempStr[Length] := ' '; END; {Copy into Reslt in reverse order} Index := 1; FOR i := Length DOWNTO 1 DO BEGIN Result[Index] := tempStr[i]; Index := Index + 1; END; {Set length of Result} Result[0] := CHR(Length); END; {IntToStr} {------------------------------------------------------------------------------} BEGIN {main program module} Randomize; {seed the random number generator} Rate := 1; FOR Count := 1 TO Num DO WaitY[Count] := 0; WHILE (Rate <= 5600) DO {get max wait time for all values of rate from 100 to 5600 by 100's} BEGIN {Variable initialization module for each new value of rate} WaitSum := 0; WaitAve := 0; FOR Rotation := 1 TO NumRot DO {do the loop NumRot times for each rate} BEGIN {Variable initialization module} Packet := 0; MessFile := 0; MessMax := 0; {Main loop : simulates 90 seconds of real time} FOR Tick := 1 TO 10000 DO BEGIN {main loop} {New message module} MessFile := MessFile + Message(Rate); IF MessFile > MessMax THEN MessMax := MessFile; {Packet assembly module} IF MessFile > 0 THEN Server(Packet, MessFile); END; {main loop} {Report module} Wait := MessMax/50 * 9/1000; {i.e., byte-time * maximum message size, in seconds} WaitSum := WaitSum + Wait; {add to WaitSum for later calc of ave} END; {rotation loop} {Calculate average maximum wait time and display} WaitAve := WaitSum / NumRot; WRITELN; WRITELN('The average maximum wait time for a rate of ', Rate:1, '/cps is: ', WaitAve:3:3); {Fill the proper element of the arrays} WaitY[Rate] := WaitAve; {Fills the array with the appropriate max wait time} Rate := Rate + Inc; {increment to next value of rate} END; {while loop} {Graphics module} SetGraph; ClrScr; SetColor(0); PlotX := 0; PlotY := 0; {Graph Area Display module} Line(70, 115, 570, 115); Line(570, 115, 570, 365); Line(570, 365, 70, 365); Line(70, 365, 70, 115); {Heading Display module} OUTTEXTXY(196, 395, 'RATE OF INCOMING MESSAGES (cps)'); WaitDisplay := "MAXIMUM WAIT TIME -sec-"; FOR Count := 1 TO 23 DO OUTTEXTXY(25, (Count * 10) + 127, WaitDisplay[Count]); OUTTEXTXY(56, 376, '0'); {Display the 'X' coordinates} FOR Count := 1 TO 5 DO BEGIN IntToStr((Count * 1000), 4, TempStr); OUTTEXTXY(TRUNC(((Count * 1000) * 0.089) + 54), 376, TempStr); END; {Display the 'Y' coordinates} FOR Count := 1 TO 10 DO BEGIN IntToStr((Count * 10), 3, TempStr); OUTTEXTXY(43, TRUNC(((Count * 10) * (-2.5)) + 365), TempStr); END; {Graph plotting module} FOR Count := 1 TO Num DO BEGIN PlotX := TRUNC((Count * 0.089) + 70); PlotY := TRUNC((WaitY[Count] * (-2.5)) + 365); PutPixel(PlotX, PlotY); END; Pause; {stop execution so user can see the resulting graph} END. {program}