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

网络

开发平台:

Unix_Linux

  1. /* TCPmtechod.c - main, TCPechod, prstats */
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <pthread.h>
  7. #include <sys/types.h>
  8. #include <sys/signal.h>
  9. #include <sys/socket.h>
  10. #include <sys/time.h>
  11. #include <sys/resource.h>
  12. #include <sys/wait.h>
  13. #include <sys/errno.h>
  14. #include <netinet/in.h>
  15. #define QLEN   32 /* maximum connection queue length */
  16. #define BUFSIZE 4096
  17. #define INTERVAL 5 /* secs */
  18. struct {
  19. pthread_mutex_t st_mutex;
  20. unsigned int st_concount;
  21. unsigned int st_contotal;
  22. unsigned long st_contime;
  23. unsigned long st_bytecount;
  24. } stats;
  25. void prstats(void);
  26. int TCPechod(int fd);
  27. int errexit(const char *format, ...);
  28. int passiveTCP(const char *service, int qlen);
  29. /*------------------------------------------------------------------------
  30.  * main - Concurrent TCP server for ECHO service
  31.  *------------------------------------------------------------------------
  32.  */
  33. int
  34. main(int argc, char *argv[])
  35. {
  36. pthread_t th;
  37. pthread_attr_t ta;
  38. char *service = "echo"; /* service name or port number */
  39. struct sockaddr_in fsin; /* the address of a client */
  40. unsigned int alen; /* length of client's address */
  41. int msock; /* master server socket */
  42. int ssock; /* slave server socket */
  43. switch (argc) {
  44. case 1:
  45. break;
  46. case 2:
  47. service = argv[1];
  48. break;
  49. default:
  50. errexit("usage: TCPechod [port]n");
  51. }
  52. msock = passiveTCP(service, QLEN);
  53. (void) pthread_attr_init(&ta);
  54. (void) pthread_attr_setdetachstate(&ta, PTHREAD_CREATE_DETACHED);
  55. (void) pthread_mutex_init(&stats.st_mutex, 0);
  56. if (pthread_create(&th, &ta, (void * (*)(void *))prstats, 0) < 0)
  57. errexit("pthread_create(prstats): %sn", strerror(errno));
  58. while (1) {
  59. alen = sizeof(fsin);
  60. ssock = accept(msock, (struct sockaddr *)&fsin, &alen);
  61. if (ssock < 0) {
  62. if (errno == EINTR)
  63. continue;
  64. errexit("accept: %sn", strerror(errno));
  65. }
  66. if (pthread_create(&th, &ta, (void * (*)(void *))TCPechod,
  67.     (void *)ssock) < 0)
  68. errexit("pthread_create: %sn", strerror(errno));
  69. }
  70. }
  71. /*------------------------------------------------------------------------
  72.  * TCPechod - echo data until end of file
  73.  *------------------------------------------------------------------------
  74.  */
  75. int
  76. TCPechod(int fd)
  77. {
  78. time_t start;
  79. char buf[BUFSIZ];
  80. int cc;
  81. start = time(0);
  82. (void) pthread_mutex_lock(&stats.st_mutex);
  83. stats.st_concount++;
  84. (void) pthread_mutex_unlock(&stats.st_mutex);
  85. while (cc = read(fd, buf, sizeof buf)) {
  86. if (cc < 0)
  87. errexit("echo read: %sn", strerror(errno));
  88. if (write(fd, buf, cc) < 0)
  89. errexit("echo write: %sn", strerror(errno));
  90. (void) pthread_mutex_lock(&stats.st_mutex);
  91. stats.st_bytecount += cc;
  92. (void) pthread_mutex_unlock(&stats.st_mutex);
  93. }
  94. (void) close(fd);
  95. (void) pthread_mutex_lock(&stats.st_mutex);
  96. stats.st_contime += time(0) - start;
  97. stats.st_concount--;
  98. stats.st_contotal++;
  99. (void) pthread_mutex_unlock(&stats.st_mutex);
  100. return 0;
  101. }
  102. /*------------------------------------------------------------------------
  103.  * prstats - print server statistical data
  104.  *------------------------------------------------------------------------
  105.  */
  106. void
  107. prstats(void)
  108. {
  109. time_t now;
  110. while (1) {
  111. (void) sleep(INTERVAL);
  112. (void) pthread_mutex_lock(&stats.st_mutex);
  113. now = time(0);
  114. (void) printf("--- %s", ctime(&now));
  115. (void) printf("%-32s: %un", "Current connections",
  116. stats.st_concount);
  117. (void) printf("%-32s: %un", "Completed connections",
  118. stats.st_contotal);
  119. if (stats.st_contotal) {
  120. (void) printf("%-32s: %.2f (secs)n",
  121. "Average complete connection time",
  122. (float)stats.st_contime /
  123. (float)stats.st_contotal);
  124. (void) printf("%-32s: %.2fn",
  125. "Average byte count",
  126. (float)stats.st_bytecount /
  127. (float)(stats.st_contotal +
  128. stats.st_concount));
  129. }
  130. (void) printf("%-32s: %lunn", "Total byte count",
  131. stats.st_bytecount);
  132. (void) pthread_mutex_unlock(&stats.st_mutex);
  133. }
  134. }