bw_tcp.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /*
  2. * bw_tcp.c - simple TCP bandwidth test
  3. *
  4. * Three programs in one -
  5. * server usage: bw_tcp -s
  6. * client usage: bw_tcp hostname [msgsize]
  7. * shutdown: bw_tcp -hostname
  8. *
  9. * Copyright (c) 1994 Larry McVoy.
  10. * Copyright (c) 2002 Carl Staelin. Distributed under the FSF GPL with
  11. * additional restriction that results may published only if
  12. * (1) the benchmark is unmodified, and
  13. * (2) the version in the sccsid below is included in the report.
  14. * Support for this development by Sun Microsystems is gratefully acknowledged.
  15. */
  16. char *id = "$Id$\n";
  17. #include "bench.h"
  18. int server_main(int ac, char **av);
  19. int client_main(int ac, char **av);
  20. void source(int data);
  21. void
  22. transfer(uint64 msgsize, int server, char *buf)
  23. {
  24. int c;
  25. while ((c = read(server, buf, msgsize)) > 0) {
  26. msgsize -= c;
  27. }
  28. if (c < 0) {
  29. perror("bw_tcp: transfer: read failed");
  30. exit(4);
  31. }
  32. }
  33. /* ARGSUSED */
  34. int
  35. client_main(int ac, char **av)
  36. {
  37. int server;
  38. uint64 msgsize = XFERSIZE;
  39. uint64 usecs;
  40. char t[512];
  41. char* buf;
  42. char* usage = "usage: %s -remotehost OR %s remotehost [msgsize]\n";
  43. int byte;
  44. if (ac != 2 && ac != 3) {
  45. (void)fprintf(stderr, usage, av[0], av[0]);
  46. exit(0);
  47. }
  48. if (ac == 3) {
  49. msgsize = bytes(av[2]);
  50. }
  51. /*
  52. * Disabler message to other side.
  53. */
  54. if (av[1][0] == '-') {
  55. server = tcp_connect(&av[1][1], TCP_DATA, SOCKOPT_REUSE);
  56. if (write(server, "0", 1) < 0) {
  57. perror("tcp write");
  58. exit(1);
  59. }
  60. exit(0);
  61. }
  62. buf = valloc(msgsize);
  63. touch(buf, msgsize);
  64. if (!buf) {
  65. perror("valloc");
  66. exit(1);
  67. }
  68. server = tcp_connect(av[1], TCP_DATA, SOCKOPT_READ|SOCKOPT_REUSE);
  69. if (server < 0) {
  70. perror("bw_tcp: could not open socket to server");
  71. exit(2);
  72. }
  73. (void) sprintf(t, "%llu", msgsize);
  74. if (write(server, t, strlen(t) + 1) != strlen(t) + 1) {
  75. perror("control write");
  76. exit(3);
  77. }
  78. /*
  79. * Send data over socket for at least 7 seconds.
  80. * This minimizes the effect of connect & opening TCP windows.
  81. */
  82. BENCH1(transfer(msgsize, server, buf), LONGER);
  83. BENCH(transfer(msgsize, server, buf), 0);
  84. out: (void) fprintf(stderr, "Socket bandwidth using %s: ", av[1]);
  85. mb(msgsize * get_n());
  86. close(server);
  87. exit(0);
  88. /*NOTREACHED*/
  89. }
  90. void
  91. child()
  92. {
  93. wait(0);
  94. signal(SIGCHLD, child);
  95. }
  96. /* ARGSUSED */
  97. int
  98. server_main(int ac, char **av)
  99. {
  100. int data, newdata;
  101. GO_AWAY;
  102. signal(SIGCHLD, child);
  103. data = tcp_server(TCP_DATA, SOCKOPT_READ|SOCKOPT_WRITE|SOCKOPT_REUSE);
  104. for ( ;; ) {
  105. newdata = tcp_accept(data, SOCKOPT_WRITE|SOCKOPT_READ);
  106. switch (fork()) {
  107. case -1:
  108. perror("fork");
  109. break;
  110. case 0:
  111. source(newdata);
  112. exit(0);
  113. default:
  114. close(newdata);
  115. break;
  116. }
  117. }
  118. }
  119. /*
  120. * Read the number of bytes to be transfered.
  121. * Write that many bytes on the data socket.
  122. */
  123. void
  124. source(int data)
  125. {
  126. int n;
  127. char t[512];
  128. char* buf;
  129. uint64 msgsize;
  130. bzero((void*)t, 512);
  131. if (read(data, t, 511) <= 0) {
  132. perror("control nbytes");
  133. exit(7);
  134. }
  135. sscanf(t, "%llu", &msgsize);
  136. buf = valloc(msgsize);
  137. touch(buf, msgsize);
  138. if (!buf) {
  139. perror("valloc");
  140. exit(1);
  141. }
  142. /*
  143. * A hack to allow turning off the absorb daemon.
  144. */
  145. if (msgsize == 0) {
  146. tcp_done(TCP_DATA);
  147. kill(getppid(), SIGTERM);
  148. exit(0);
  149. }
  150. /*
  151. fprintf(stderr, "server: msgsize=%llu, t=%s\n", msgsize, t); fflush(stderr);
  152. /* XXX */
  153. while ((n = write(data, buf, msgsize)) > 0) {
  154. #ifdef TOUCH
  155. touch(buf, msgsize);
  156. #endif
  157. ;
  158. }
  159. free(buf);
  160. }
  161. int
  162. main(int ac, char **av)
  163. {
  164. char* usage = "Usage: %s -s OR %s -serverhost OR %s serverhost [msgsize]\n";
  165. if (ac < 2 || 3 < ac) {
  166. fprintf(stderr, usage, av[0], av[0], av[0]);
  167. exit(1);
  168. }
  169. if (ac == 2 && !strcmp(av[1], "-s")) {
  170. if (fork() == 0) {
  171. server_main(ac, av);
  172. }
  173. exit(0);
  174. } else {
  175. client_main(ac, av);
  176. }
  177. return(0);
  178. }