lat_udp.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * udp_xact.c - simple UDP transaction latency test
  3. *
  4. * Three programs in one -
  5. * server usage: udp_xact -s
  6. * client usage: udp_xact hostname
  7. * shutdown: udp_xact -hostname
  8. *
  9. * Copyright (c) 1994 Larry McVoy. Distributed under the FSF GPL with
  10. * additional restriction that results may published only if
  11. * (1) the benchmark is unmodified, and
  12. * (2) the version in the sccsid below is included in the report.
  13. * Support for this development by Sun Microsystems is gratefully acknowledged.
  14. */
  15. char *id = "$Id$\n";
  16. #include "bench.h"
  17. void client_main(int ac, char **av);
  18. void server_main(int ac, char **av);
  19. void
  20. timeout()
  21. {
  22. fprintf(stderr, "Recv timed out\n");
  23. exit(1);
  24. }
  25. void
  26. doit(int sock, int seq)
  27. {
  28. int net = htonl(seq);
  29. int ret;
  30. if (send(sock, &net, sizeof(net), 0) != sizeof(net)) {
  31. perror("lat_udp client: send failed");
  32. exit(5);
  33. }
  34. if (recv(sock, &ret, sizeof(ret), 0) != sizeof(ret)) {
  35. perror("lat_udp client: recv failed");
  36. exit(5);
  37. }
  38. }
  39. int
  40. main(int ac, char **av)
  41. {
  42. if (sizeof(int) != 4) {
  43. fprintf(stderr, "lat_udp: Wrong sequence size\n");
  44. return(1);
  45. }
  46. if (ac != 2 && ac != 3) {
  47. fprintf(stderr, "Usage: %s -s OR %s [-]serverhost [proto]\n",
  48. av[0], av[0]);
  49. return(1);
  50. }
  51. if (!strcmp(av[1], "-s")) {
  52. if (fork() == 0) {
  53. server_main(ac, av);
  54. }
  55. return(0);
  56. } else {
  57. client_main(ac, av);
  58. }
  59. return(0);
  60. }
  61. void
  62. client_main(int ac, char **av)
  63. {
  64. int sock;
  65. int seq = -1;
  66. char *server;
  67. char buf[256];
  68. if (ac != 2) {
  69. fprintf(stderr, "Usage: %s hostname\n", av[0]);
  70. exit(1);
  71. }
  72. server = av[1][0] == '-' ? &av[1][1] : av[1];
  73. sock = udp_connect(server, UDP_XACT, SOCKOPT_NONE);
  74. /*
  75. * Stop server code.
  76. */
  77. if (av[1][0] == '-') {
  78. while (seq-- > -5) {
  79. int net = htonl(seq);
  80. (void) send(sock, &net, sizeof(net), 0);
  81. }
  82. exit(0);
  83. }
  84. signal(SIGALRM, timeout);
  85. alarm(15);
  86. BENCH(doit(sock, ++seq), MEDIUM);
  87. sprintf(buf, "UDP latency using %s", server);
  88. micro(buf, get_n());
  89. exit(0);
  90. }
  91. /* ARGSUSED */
  92. void
  93. server_main(int ac, char **av)
  94. {
  95. int net, sock, sent, namelen, seq = 0;
  96. struct sockaddr_in it;
  97. GO_AWAY;
  98. sock = udp_server(UDP_XACT, SOCKOPT_NONE);
  99. while (1) {
  100. namelen = sizeof(it);
  101. if (recvfrom(sock, (void*)&sent, sizeof(sent), 0,
  102. (struct sockaddr*)&it, &namelen) < 0) {
  103. fprintf(stderr, "lat_udp server: recvfrom: got wrong size\n");
  104. exit(9);
  105. }
  106. sent = ntohl(sent);
  107. if (sent < 0) {
  108. udp_done(UDP_XACT);
  109. exit(0);
  110. }
  111. if (sent != ++seq) {
  112. seq = sent;
  113. }
  114. net = htonl(seq);
  115. if (sendto(sock, (void*)&net, sizeof(net), 0,
  116. (struct sockaddr*)&it, sizeof(it)) < 0) {
  117. perror("lat_udp sendto");
  118. exit(9);
  119. }
  120. }
  121. }