web01.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /* include web1 */
  2. #include "unpthread.h"
  3. #include <thread.h> /* Solaris threads */
  4. #define MAXFILES 20
  5. #define SERV "80" /* port number or service name */
  6. struct file {
  7. char *f_name; /* filename */
  8. char *f_host; /* hostname or IP address */
  9. int f_fd; /* descriptor */
  10. int f_flags; /* F_xxx below */
  11. pthread_t f_tid; /* thread ID */
  12. } file[MAXFILES];
  13. #define F_CONNECTING 1 /* connect() in progress */
  14. #define F_READING 2 /* connect() complete; now reading */
  15. #define F_DONE 4 /* all done */
  16. #define GET_CMD "GET %s HTTP/1.0\r\n\r\n"
  17. int nconn, nfiles, nlefttoconn, nlefttoread;
  18. void *do_get_read(void *);
  19. void home_page(const char *, const char *);
  20. void write_get_cmd(struct file *);
  21. int
  22. main(int argc, char **argv)
  23. {
  24. int i, n, maxnconn;
  25. pthread_t tid;
  26. struct file *fptr;
  27. if (argc < 5)
  28. err_quit("usage: web <#conns> <IPaddr> <homepage> file1 ...");
  29. maxnconn = atoi(argv[1]);
  30. nfiles = min(argc - 4, MAXFILES);
  31. for (i = 0; i < nfiles; i++) {
  32. file[i].f_name = argv[i + 4];
  33. file[i].f_host = argv[2];
  34. file[i].f_flags = 0;
  35. }
  36. printf("nfiles = %d\n", nfiles);
  37. home_page(argv[2], argv[3]);
  38. nlefttoread = nlefttoconn = nfiles;
  39. nconn = 0;
  40. /* end web1 */
  41. /* include web2 */
  42. while (nlefttoread > 0) {
  43. while (nconn < maxnconn && nlefttoconn > 0) {
  44. /* 4find a file to read */
  45. for (i = 0 ; i < nfiles; i++)
  46. if (file[i].f_flags == 0)
  47. break;
  48. if (i == nfiles)
  49. err_quit("nlefttoconn = %d but nothing found", nlefttoconn);
  50. file[i].f_flags = F_CONNECTING;
  51. Pthread_create(&tid, NULL, &do_get_read, &file[i]);
  52. file[i].f_tid = tid;
  53. nconn++;
  54. nlefttoconn--;
  55. }
  56. if ( (n = thr_join(0, &tid, (void **) &fptr)) != 0)
  57. errno = n, err_sys("thr_join error");
  58. nconn--;
  59. nlefttoread--;
  60. printf("thread id %d for %s done\n", tid, fptr->f_name);
  61. }
  62. exit(0);
  63. }
  64. /* end web2 */
  65. /* include do_get_read */
  66. void *
  67. do_get_read(void *vptr)
  68. {
  69. int fd, n;
  70. char line[MAXLINE];
  71. struct file *fptr;
  72. fptr = (struct file *) vptr;
  73. fd = Tcp_connect(fptr->f_host, SERV);
  74. fptr->f_fd = fd;
  75. printf("do_get_read for %s, fd %d, thread %d\n",
  76. fptr->f_name, fd, fptr->f_tid);
  77. write_get_cmd(fptr); /* write() the GET command */
  78. /* 4Read server's reply */
  79. for ( ; ; ) {
  80. if ( (n = Read(fd, line, MAXLINE)) == 0)
  81. break; /* server closed connection */
  82. printf("read %d bytes from %s\n", n, fptr->f_name);
  83. }
  84. printf("end-of-file on %s\n", fptr->f_name);
  85. Close(fd);
  86. fptr->f_flags = F_DONE; /* clears F_READING */
  87. return(fptr); /* terminate thread */
  88. }
  89. /* end do_get_read */
  90. /* include write_get_cmd */
  91. void
  92. write_get_cmd(struct file *fptr)
  93. {
  94. int n;
  95. char line[MAXLINE];
  96. n = snprintf(line, sizeof(line), GET_CMD, fptr->f_name);
  97. Writen(fptr->f_fd, line, n);
  98. printf("wrote %d bytes for %s\n", n, fptr->f_name);
  99. fptr->f_flags = F_READING; /* clears F_CONNECTING */
  100. }
  101. /* end write_get_cmd */
  102. /* include home_page */
  103. void
  104. home_page(const char *host, const char *fname)
  105. {
  106. int fd, n;
  107. char line[MAXLINE];
  108. fd = Tcp_connect(host, SERV); /* blocking connect() */
  109. n = snprintf(line, sizeof(line), GET_CMD, fname);
  110. Writen(fd, line, n);
  111. for ( ; ; ) {
  112. if ( (n = Read(fd, line, MAXLINE)) == 0)
  113. break; /* server closed connection */
  114. printf("read %d bytes of home page\n", n);
  115. /* do whatever with data */
  116. }
  117. printf("end-of-file on home page\n");
  118. Close(fd);
  119. }
  120. /* end home_page */