BenchTCP.Mod 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. MODULE BenchTCP; (* pjm *)
  2. IMPORT Kernel, IP, KernelLog, TCP, DNS, Strings, Commands;
  3. CONST
  4. BufSize = 32768; (* multiple of 1024 *)
  5. CloseTimeout = 10000; (* ms *)
  6. EchoPort = 7; DiscardPort = 9; (*ChargenPort = 19;*) TimePort = 37;
  7. Header = "BenchTCP: "; (* in log *)
  8. TYPE
  9. Bytes = POINTER TO ARRAY OF CHAR;
  10. TYPE
  11. Sender = OBJECT
  12. VAR
  13. res: WORD;
  14. c: TCP.Connection; num, num0: LONGINT; buf: Bytes; done: BOOLEAN;
  15. PROCEDURE &Init*(c: TCP.Connection; buf: Bytes; num: LONGINT);
  16. BEGIN
  17. ASSERT(LEN(buf^) >= 1024);
  18. SELF.c := c; SELF.buf := buf; SELF.num := num;
  19. done := FALSE
  20. END Init;
  21. PROCEDURE Join(): WORD;
  22. BEGIN {EXCLUSIVE}
  23. AWAIT(done);
  24. RETURN res
  25. END Join;
  26. BEGIN {ACTIVE}
  27. res := 0;
  28. WHILE (res = 0) & (num > 0) DO
  29. num0 := LEN(buf^) DIV 1024;
  30. IF num0 > num THEN num0 := num END;
  31. c.Send(buf^, 0, num0*1024, FALSE, res);
  32. DEC(num, num0)
  33. END;
  34. BEGIN {EXCLUSIVE} done := TRUE END
  35. END Sender;
  36. TYPE
  37. Tester = OBJECT
  38. VAR
  39. res: WORD;
  40. c: TCP.Connection; num, num0, port, total, len: LONGINT; fip: IP.Adr;
  41. timer: Kernel.MilliTimer; sender: Sender; server: ARRAY 64 OF CHAR;
  42. time:HUGEINT;
  43. PROCEDURE &Init*(CONST server: ARRAY OF CHAR; num, port: LONGINT);
  44. BEGIN
  45. COPY(server, SELF.server); SELF.num := num; SELF.port := port;
  46. DNS.HostByName(server, fip, res);
  47. IF res # 0 THEN Message(server, " DNS lookup failed", res) END
  48. END Init;
  49. BEGIN {ACTIVE}
  50. IF res = 0 THEN
  51. Message(server, " opening", 0);
  52. Kernel.SetTimer(timer, 0);
  53. NEW(c); c.Open(TCP.NilPort, fip, port, res);
  54. IF res = 0 THEN
  55. IF port=TimePort THEN
  56. c.Receive(buf^, 0, 4, 4, len, res);
  57. total:=len;
  58. time:=((HUGEINT(ORD(buf[0]))*256+ORD(buf[1]))*256 + ORD(buf[2]))*256 + ORD(buf[3]);
  59. KernelLog.String("ClientTime: "); KernelLog.Int(time,6); KernelLog.String(" : ");
  60. KernelLog.Int(time MOD 60,6); time:=time DIV 60; KernelLog.String("sec");
  61. KernelLog.Int(time MOD 60,6); time:=time DIV 60; KernelLog.String("min");
  62. KernelLog.Int(time MOD 24,6); time:=time DIV 24; KernelLog.String("hh");
  63. KernelLog.Int(time,7); KernelLog.String("days since 1.1.1900");
  64. KernelLog.Ln;
  65. ELSE
  66. NEW(sender, c, buf, num);
  67. IF port = EchoPort THEN
  68. total := num*2;
  69. WHILE (res = 0) & (num > 0) DO
  70. num0 := LEN(buf^) DIV 1024;
  71. IF num0 > num THEN num0 := num END;
  72. c.Receive(buf^, 0, num0*1024, num0*1024, len, res);
  73. DEC(num, num0)
  74. END
  75. ELSE
  76. total := num
  77. END;
  78. IF res = 0 THEN res := sender.Join() END;
  79. END;
  80. c.Close();
  81. IF res = 0 THEN c.AwaitState(TCP.ClosedStates, {}, CloseTimeout, res) END;
  82. IF (res = 0)&(port#TimePort) THEN Report(Kernel.Elapsed(timer), port, total, server) END
  83. END;
  84. IF res # 0 THEN Message(server, " connection failed", res) END
  85. END
  86. END Tester;
  87. VAR
  88. buf: Bytes;
  89. PROCEDURE Message(CONST msg1, msg2: ARRAY OF CHAR; res: WORD);
  90. BEGIN
  91. KernelLog.String(Header); KernelLog.String(msg1); KernelLog.String(msg2);
  92. IF res # 0 THEN
  93. KernelLog.String(", res="); KernelLog.Ln;
  94. END;
  95. KernelLog.Ln;
  96. END Message;
  97. PROCEDURE Report(ms, port, total: LONGINT; CONST msg: ARRAY OF CHAR);
  98. VAR
  99. realStr: ARRAY 128 OF CHAR;
  100. BEGIN
  101. KernelLog.String(Header);
  102. IF port = DiscardPort THEN KernelLog.String("Discard ");
  103. ELSIF port = EchoPort THEN KernelLog.String("Echo ");
  104. ELSE KernelLog.String("Chargen ");
  105. END;
  106. KernelLog.Int(total, 0); KernelLog.String("KB, ");
  107. KernelLog.Int(ms, 0); KernelLog.String("ms, ");
  108. IF ms # 0 THEN
  109. KernelLog.Int(ENTIER(total/ms*1000.0), 0); KernelLog.String("KB/s,");
  110. Strings.FloatToStr(total/1024.0*8/ms*1000.0, 0,0,0,realStr);
  111. KernelLog.String(realStr); KernelLog.String("Mb/s");
  112. ELSE
  113. KernelLog.String(" N/A");
  114. END;
  115. KernelLog.String(", "); KernelLog.String(msg);
  116. KernelLog.Ln;
  117. END Report;
  118. (** server KB *)
  119. PROCEDURE Discard*(context : Commands.Context);
  120. VAR t: Tester; num: LONGINT; server: ARRAY 64 OF CHAR;
  121. BEGIN
  122. context.arg.SkipWhitespace; context.arg.String(server);
  123. context.arg.SkipWhitespace; context.arg.Int(num, FALSE);
  124. NEW(t, server, num, DiscardPort);
  125. END Discard;
  126. (** server KB *)
  127. PROCEDURE Echo*(context : Commands.Context);
  128. VAR t: Tester; num: LONGINT; server: ARRAY 64 OF CHAR;
  129. BEGIN
  130. context.arg.SkipWhitespace; context.arg.String(server);
  131. context.arg.SkipWhitespace; context.arg.Int(num, FALSE);
  132. NEW(t, server, num, EchoPort);
  133. END Echo;
  134. (** server KB *)
  135. PROCEDURE Time*(context : Commands.Context);
  136. VAR t: Tester; num: LONGINT; server: ARRAY 64 OF CHAR;
  137. BEGIN
  138. context.arg.SkipWhitespace; context.arg.String(server);
  139. NEW(t, server, 0, TimePort);
  140. END Time;
  141. BEGIN
  142. NEW(buf, BufSize)
  143. END BenchTCP.
  144. BenchTCP.Discard 192.168.0.2 1000
  145. BenchTCP.Discard portnoy.ethz.ch 10
  146. BenchTCP.Discard lillian.ethz.ch 40000
  147. BenchTCP.Discard bluebottle.ethz.ch 40
  148. BenchTCP.Echo lillian.ethz.ch 40000 ~
  149. BenchTCP.Echo bluebottle.ethz.ch 40
  150. BenchTCP.Time 127.0.0.1 ~
  151. BenchTCP.Echo FE80::230:1BFF:FEAF:EEF2 100000~
  152. BenchTCP.Discard FE80::230:1BFF:FEAF:EEF2 100000~
  153. System.Free BenchTCP