TCPtecho.c
上传用户:wei_4586
上传日期:2008-05-28
资源大小:18k
文件大小:4k
源码类别:

网络

开发平台:

Unix_Linux

  1. /* TCPtecho.c - main, TCPtecho, reader, writer, mstime */
  2. #include <sys/types.h>
  3. #include <sys/param.h>
  4. #include <sys/ioctl.h>
  5. #include <sys/time.h>
  6. #include <sys/socket.h>
  7. #include <unistd.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <stdio.h>
  11. extern int errno;
  12. int TCPtecho(fd_set *pafds, int nfds, int ccount, int hcount);
  13. int reader(int fd, fd_set *pfdset);
  14. int writer(int fd, fd_set *pfdset);
  15. int errexit(const char *format, ...);
  16. int connectTCP(const char *host, const char *service);
  17. long mstime(unsigned long *);
  18. #define BUFSIZE 4096 /* write buffer size */
  19. #define CCOUNT 64*1024 /* default character count */
  20. #define USAGE "usage: TCPtecho [ -c count ] host1 host2...n"
  21. char *hname[NOFILE]; /* fd to host name mapping */
  22. int rc[NOFILE], wc[NOFILE]; /* read/write character counts */
  23. char buf[BUFSIZE]; /* read/write data buffer */
  24. /*------------------------------------------------------------------------
  25.  * main - concurrent TCP client for ECHO service timing
  26.  *------------------------------------------------------------------------
  27.  */
  28. int
  29. main(int argc, char *argv[])
  30. {
  31. int ccount = CCOUNT;
  32. int i, hcount, maxfd, fd;
  33. int one = 1;
  34. fd_set afds;
  35. hcount = 0;
  36. maxfd = -1;
  37. for (i=1; i<argc; ++i) {
  38. if (strcmp(argv[i], "-c") == 0) {
  39. if (++i < argc && (ccount = atoi(argv[i])))
  40. continue;
  41. errexit(USAGE);
  42. }
  43. /* else, a host */
  44. fd = connectTCP(argv[i], "echo");
  45. if (ioctl(fd, FIONBIO, (char *)&one))
  46. errexit("can't mark socket nonblocking: %sn",
  47. strerror(errno));
  48. if (fd > maxfd)
  49. maxfd = fd;
  50. hname[fd] = argv[i];
  51. ++hcount;
  52. FD_SET(fd, &afds);
  53. }
  54. TCPtecho(&afds, maxfd+1, ccount, hcount);
  55. exit(0);
  56. }
  57. /*------------------------------------------------------------------------
  58.  * TCPtecho - time TCP ECHO requests to multiple servers
  59.  *------------------------------------------------------------------------
  60.  */
  61. int
  62. TCPtecho(fd_set *pafds, int nfds, int ccount, int hcount)
  63. {
  64. fd_set rfds, wfds; /* read/write fd sets */
  65. fd_set rcfds, wcfds; /* read/write fd sets (copy) */
  66. int fd, i;
  67. for (i=0; i<BUFSIZE; ++i) /* echo data */
  68. buf[i] = 'D';
  69. memcpy(&rcfds, pafds, sizeof(rcfds));
  70. memcpy(&wcfds, pafds, sizeof(wcfds));
  71. for (fd=0; fd<nfds; ++fd)
  72. rc[fd] = wc[fd] = ccount;
  73. (void) mstime((unsigned long *)0); /* set the epoch */
  74. while (hcount) {
  75. memcpy(&rfds, &rcfds, sizeof(rfds));
  76. memcpy(&wfds, &wcfds, sizeof(wfds));
  77. if (select(nfds, &rfds, &wfds, (fd_set *)0,
  78. (struct timeval *)0) < 0)
  79. errexit("select failed: %sn", strerror(errno));
  80. for (fd=0; fd<nfds; ++fd) {
  81. if (FD_ISSET(fd, &rfds))
  82. if (reader(fd, &rcfds) == 0)
  83. hcount--;
  84. if (FD_ISSET(fd, &wfds))
  85. writer(fd, &wcfds);
  86. }
  87. }
  88. }
  89. /*------------------------------------------------------------------------
  90.  * reader - handle ECHO reads
  91.  *------------------------------------------------------------------------
  92.  */
  93. int
  94. reader(int fd, fd_set *pfdset)
  95. {
  96. unsigned long now;
  97. int cc;
  98. cc = read(fd, buf, sizeof(buf));
  99. if (cc < 0)
  100. errexit("read: %sn", strerror(errno));
  101. if (cc == 0)
  102. errexit("read: premature end of filen");
  103. rc[fd] -= cc;
  104. if (rc[fd])
  105. return 1;
  106. (void) mstime(&now);
  107. printf("%s: %d msn", hname[fd], now);
  108. (void) close(fd);
  109. FD_CLR(fd, pfdset);
  110. return 0;
  111. }
  112. /*------------------------------------------------------------------------
  113.  * writer - handle ECHO writes
  114.  *------------------------------------------------------------------------
  115.  */
  116. int
  117. writer(int fd, fd_set *pfdset)
  118. {
  119. int cc;
  120. cc = write(fd, buf, MIN((int)sizeof(buf), wc[fd]));
  121. if (cc < 0)
  122. errexit("read: %sn", strerror(errno));
  123. wc[fd] -= cc;
  124. if (wc[fd] == 0) {
  125. (void) shutdown(fd, 1);
  126. FD_CLR(fd, pfdset);
  127. }
  128. }
  129. /*------------------------------------------------------------------------
  130.  * mstime - report the number of milliseconds elapsed
  131.  *------------------------------------------------------------------------
  132.  */
  133. long
  134. mstime(unsigned long *pms)
  135. {
  136. static struct timeval epoch;
  137. struct timeval now;
  138. if (gettimeofday(&now, (struct timezone *)0))
  139. errexit("gettimeofday: %sn", strerror(errno));
  140. if (!pms) {
  141. epoch = now;
  142. return 0;
  143. }
  144. *pms = (now.tv_sec - epoch.tv_sec) * 1000;
  145. *pms += (now.tv_usec - epoch.tv_usec + 500)/ 1000;
  146. return *pms;
  147. }