// have not yet read an EOF on stdin, and at least one // byte of data in the to buffer if (stdineof == 0 && toiptr < &to[MAXLINE]) FD_SET(STDIN_FILENO, &rset); /* read from stdin */
// at least one byte if data in the fr buffer if (friptr < &fr[MAXLINE]) FD_SET(sockfd, &rset); /* read from socket */
// there is data to write to server in the to buffer if (tooptr != toiptr) FD_SET(sockfd, &wset); /* data to write to socket */
// there is data to send to stdout in the fr buffer if (froptr != friptr) FD_SET(STDOUT_FILENO, &wset); /* data to write to stdout */
Select(maxfdp1, &rset, &wset, NULL, NULL);
if (FD_ISSET(STDIN_FILENO, &rset)) { // stdin is readable if ((n = read(STDIN_FILENO, toiptr, &to[MAXLINE] - toiptr)) < 0) { if (errno != EWOULDBLOCK) err_sys("read error on stdin"); } elseif (n == 0) { // receive EOF from stdin stdineof = 1; /* all done with stdin */ if (tooptr == toiptr) // no data in the to buffer Shutdown(sockfd, SHUT_WR); /* send FIN */ } else { toiptr += n; /* read data from stdin */ FD_SET(sockfd, &wset); /* try and write to socket below */ } }
if (FD_ISSET(sockfd, &rset)) { // socket is readable if ((n = read(sockfd, friptr, &fr[MAXLINE] - friptr)) < 0) { if (errno != EWOULDBLOCK) err_sys("read error on socket"); } elseif (n == 0) { // server closed if (stdineof) return; /* normal termination */ else err_quit("str_cli: server terminated prematurely"); } else { friptr += n; /* read data from socket */ FD_SET(STDOUT_FILENO, &wset); /* try and write below */ } }
// stdout is writable and there's data in the fr buffer if (FD_ISSET(STDOUT_FILENO, &wset) && ((n = friptr - froptr) > 0)) { if ((nwritten = write(STDOUT_FILENO, froptr, n)) < 0) { if (errno != EWOULDBLOCK) err_sys("write error to stdout"); } else { froptr += nwritten; /* writte data into stdout */ if (froptr == friptr) froptr = friptr = fr; /* back to beginning of buffer */ } }
// socket is writable and there's data in the to buffer if (FD_ISSET(sockfd, &wset) && ((n = toiptr - tooptr) > 0)) { if ((nwritten = write(sockfd, tooptr, n)) < 0) { if (errno != EWOULDBLOCK) err_sys("write error to socket"); } else { tooptr += nwritten; /* write data into socket */ if (tooptr == toiptr) { toiptr = tooptr = to; /* back to beginning of buffer */ if (stdineof) Shutdown(sockfd, SHUT_WR); /* send FIN */ } } } } }
intmain(int argc, char **argv) { int i, fd, n, maxnconn, flags, error; char buf[MAXLINE]; fd_set rs, ws;
if (argc < 5) err_quit("usage: web <nconn> <hostname> <homepage> <file1> ..."); maxnconn = atoi(argv[1]); /* maximum number of connections */ nfiles = min(argc - 4, MAXFILES); /* number of files */ /* fill in with the information from the command-line arguments */ for (i = 0; i < nfiles; i++) { file[i].f_name = argv[i + 4]; file[i].f_host = argv[2]; file[i].f_flags = 0; }
/* create a TCP connection to he server's home page */ home_page(argv[2], argv[3]);
while (nlefttoread > 0) { /* there are additional connections to establish */ while (nconn < maxnconn && nlefttoconn > 0) { for (i = 0 ; i < nfiles; i++) // find a nonconnected file if (file[i].f_flags == 0) break; if (i == nfiles) /* no files need to be connected */ err_quit("nlefttoconn = %d but nothing found", nlefttoconn); start_connect(&file[i]); nconn++; nlefttoconn--; }