Exemplo n.º 1
0
void
start_connect(struct file *fptr)
{
	int				fd, flags, n;
	struct addrinfo	*ai;

	ai = Host_serv(fptr->f_host, SERV, 0, SOCK_STREAM);

	fd = Socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
	fptr->f_fd = fd;
	printf("start_connect for %s, fd %d\n", fptr->f_name, fd);

		/* 4Set socket nonblocking */
	flags = Fcntl(fd, F_GETFL, 0);
	Fcntl(fd, F_SETFL, flags | O_NONBLOCK);

		/* 4Initiate nonblocking connect to the server. */
	if ( (n = connect(fd, ai->ai_addr, ai->ai_addrlen)) < 0) {
		if (errno != EINPROGRESS)
			err_sys("nonblocking connect error");
		fptr->f_flags = F_CONNECTING;
		FD_SET(fd, &rset);			/* select for reading and writing */
		FD_SET(fd, &wset);
		if (fd > maxfd)
			maxfd = fd;

	} else if (n >= 0)				/* connect is already done */
		write_get_cmd(fptr);	/* write() the GET command */
}
Exemplo n.º 2
0
void *do_get_read(void *vptr)
{
	int fd,n;
	char line[MAXLINE];
	struct file *fptr;
	fptr = (struct file *) vptr;
	fd = tcp_connect(fptr->f_host,SERV);
	fptr->f_fd = fd;
	printf("do_get_read for %s, fd %d, thread %d\n",fptr->f_name,fd,fptr->f_tid);

	write_get_cmd(fptr);	// write() the GET command

	// read server's reply
	for (;;) {
		if ((n=read(fd,line,MAXLINE))==0)
			break;	// server closed connection
		printf("read %d bytes for %s\n",n,fptr->f_name);
	}

	printf("end-of-file on %s\n",fptr->f_name);
	close(fd);
	pthread_mutex_lock(&ndone_mutex);
	fptr->f_flags = F_DONE;	// clear F_READING
	ndone++;
	pthread_cond_signal(&ndone_cond);	// 叫醒所有在等待ndone_cond的thread
	pthread_mutex_unlock(&ndone_mutex);	// 釋放ndone_mutex資源

	return (fptr);
}
Exemplo n.º 3
0
void *
do_get_read(void *vptr)
{
  int         fd, n;
  char        line[MAXLINE];
  struct file     *fptr;

  fptr = (struct file *) vptr;

  fd = Tcp_connect(fptr->f_host, SERV);
  fptr->f_fd = fd;
  printf("do_get_read for %s, fd %d, thread %d\n",
      fptr->f_name, fd, fptr->f_tid);

  write_get_cmd(fptr);  /* write() the GET command */

    /* 4Read server's reply */
  for ( ; ; ) {
    if ( (n = Read(fd, line, MAXLINE)) == 0)
      break;    /* server closed connection */

    printf("read %d bytes from %s\n", n, fptr->f_name);
  }
  printf("end-of-file on %s\n", fptr->f_name);
  Close(fd);
  fptr->f_flags = F_DONE;   /* clears F_READING */

  Pthread_mutex_lock(&ndone_mutex);
  ndone++;
  Pthread_cond_signal(&ndone_cond);
  Pthread_mutex_unlock(&ndone_mutex);

  return(fptr);   /* terminate thread */
}
Exemplo n.º 4
0
void start_connect(struct file *fptr)
{
    int fd, flags, n;
    struct addrinfo *ai;

    ai = Host_serv(fptr -> f_host, SERV, 0, SOCK_STREAM);
    fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);

    fptr->f_fd = fd;
    printf("start_connect for %s, fd %d\n", fptr->f_name, fd);

    flags = fcntl(fd, F_GETFL, 0);
    fcntl(fd, F_SETFL, flags | O_NONBLOCK);

    if((n = connect(fd, ai->ai_addr, ai->ai_addrlen)) < 0)
    {
        if(errno != EINPROGRESS)
            err_sys("nonblocking connect error");

        fptr->f_flags = F_CONNECTING;

        FD_SET(fd, &rset);
        FD_SET(fd, &wset);

        maxfd = max(maxfd, fd);
    }
    else
        write_get_cmd(fptr);
}
Exemplo n.º 5
0
void start_connect(struct file *fptr){
	int fd, flags, n;
	struct addrinfo *ai;

	ai = _Host_serv(fptr->f_host, SERV, 0, SOCK_STREAM);
	fd = _Socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
	fptr->f_fd = fd;
	printf("Start_connect for %s, fd %d\n", fptr->f_name, fd );

	flags = _Fcntl(fd, F_GETFL, 0);
	_Fcntl(fd, F_SETFL, flags | O_NONBLOCK);

	n = connect(fd, ai->ai_addr, ai->ai_addrlen);
	if(n < 0){
		if(errno != EINPROGRESS)
			error("Nonblocking connect error");	
		fptr->f_flags = F_CONNECTING;
		FD_SET(fd, &rset);
		FD_SET(fd, &wset);

		if(fd > max_fd)
			max_fd = fd;
	}else
		if(n >= 0)
			write_get_cmd(fptr);
}
Exemplo n.º 6
0
void start_connect(const file *fptr){
	int n,fd,flags;
	struct addrinfo hint,*res,*ressave;
	bzero(&hint);
	hint.ai_flags = AI_CANONNAME;
	hint.ai_family = AF_UNSPEC;
	hint.ai_socktype = SOCK_STREAM;
	if((n = getaddrinfo(fptr->f_host,SERV,&hint,&res)) != 0)
		err_quit("start connect error for %s %s :%s\n",fptr->f_name,SERV,gai_strerror(n));
	fd = Socket(res->ai_family,res->ai_socktype,res->ai_protocol);
	fptr->f_fd = fd;
	flags = Fctnl(fd,F_GETFL,0);
	Fctnl(fd,F_SETFL,flags | O_NONBLOCK);
	if((n = Connect(fd,ai_addr,ai_addrlen)) < 0){
		if(errno != EINPROGRESS)
			err_sys("nonblocking connection error!");
		fptr->flags = F_CONNECTING;
		FD_SET(fd,&rset);
		FD_SET(fd,&wset);
		if(fd > maxfd)
			maxfd = fd;	
	}else{
		write_get_cmd(fptr);
	}
}
Exemplo n.º 7
0
void
start_connect(struct file *fptr)
{
    int             fd, flags, n;
    struct addrinfo *ai;
    
    ai = Host_serv(fptr->f_host, SERV, 0, SOCK_STREAM);
    
    fd = Socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
    fptr->f_fd = fd;
    printf("start_connect for %s, fd %d\n", fptr->f_name, fd);
    
    /* 4Set socket nonblocking */
    flags = Fcntl(fd, F_GETFL, 0);
    Fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    
    /* 4Initiate nonblocking connect to the server. */
    if ( (n = connect(fd, ai->ai_addr, ai->ai_addrlen)) < 0)
    {
        if (errno != EINPROGRESS)
            err_sys("nonblocking connect error");
        fptr->f_flags = F_CONNECTING;
        //register
        int ret = 0;
        struct kevent changes[1];
        EV_SET(&changes[0], fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL);
        ret = kevent(kq, changes, 1, NULL, 0, NULL);
        if (ret < 0) {
            err_sys("kevent()");
        }
        EV_SET(&changes[0], fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
        ret = kevent(kq, changes, 1, NULL, 0, NULL);
        
        if (fd > maxfd)
            maxfd = fd;
        
    }
    else if (n >= 0)              /* connect is already done */
    {
        write_get_cmd(fptr);    /* write() the GET command */
    }
}
Exemplo n.º 8
0
void *do_get_read(void *vptr)
{
	int					fd, n;
	char				line[MAXLINE];
	struct file			*fptr;
	rio_t rio;

	fptr = (struct file *) vptr;

	fd = tcpConnect(fptr->f_host, SERV);
	fptr->f_fd = fd;
	printf("do_get_read for name:%s host:%s, fd %d, thread %d\n",
			fptr->f_name,fptr->f_host, fd, fptr->f_tid);

	write_get_cmd(fptr);	/* write() the GET command */

	rio_readinitb(&rio,fd);
	while((n = rio_readlineb(&rio,line,sizeof(line))) > 1)
	{
		printf("read %d bytes from name:%s host:%s\n", n, fptr->f_name,fptr->f_host);
		if (strcmp(line, END_OF_HTML) == 0)
		{
			break;
		}
		parseUrl(line,fptr->f_host);
	}
	printf("end-of-file on name:%s host:%s\n", fptr->f_name,fptr->f_host);
	close(fd);
	fptr->f_flags = F_DONE;		/* clears F_READING */

	pthread_mutex_lock(&ndone_mutex);
	ndone++;
	pthread_cond_signal(&ndone_cond);
	pthread_mutex_unlock(&ndone_mutex);

	return(fptr);		/* terminate thread */
}
Exemplo n.º 9
0
void start_connect(struct file *fptr)
{
    int fd, flags, n;
    struct addrinfo *ai;

    if ((ai = host_serv(fptr->f_host, SERV, 0, SOCK_STREAM)) < 0) {
        err_sys("host_serv error");
    }
    if ((fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) {
        err_sys("socket error");
    }
    fptr->f_fd = fd;
    printf("start_connect for %s, fd %d\n", fptr->f_name, fd);

    // set socket nonblocking
    if ((flags = fcntl(fd, F_GETFL, 0)) < 0) {
        err_sys("fcntl error");
    }
    if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
        err_sys("fcntl error");
    }

    // initiate nonblocking connect to the server
    if ((n = connect(fd, ai->ai_addr, ai->ai_addrlen)) < 0) {
        if (errno != EINPROGRESS) {
            err_sys("nonblocking connect error");
        }
        fptr->f_flags = F_CONNECTING;
        FD_SET(fd, &rset); // select for reading and writing
        FD_SET(fd, &wset);
        if (fd > maxfd) {
            maxfd = fd;
        }
    } else if (n >= 0) { // connect is already done
        write_get_cmd(fptr); // write the GET command
    }
}
Exemplo n.º 10
0
int
main(int argc, char **argv)
{
	int		i, fd, n, maxnconn, flags, error, ret, index;
	char	buf[MAXLINE];
	fd_set	rs, ws;
    
	if (argc < 5)
		err_quit("usage: web <#conns> <hostname> <homepage> <file1> ...");
	maxnconn = atoi(argv[1]);
    
	nfiles = min(argc - 4, MAXFILES);
	for (i = 0; i < nfiles; i++) {
		file[i].f_name = argv[i + 4];
		file[i].f_host = argv[2];
		file[i].f_flags = 0;
	}
	printf("nfiles = %d\n", nfiles);
    
	home_page(argv[2], argv[3]);
    
    kq = kqueue();

	maxfd = -1;
	nlefttoread = nlefttoconn = nfiles;
	nconn = 0;
    /* end web1 */
    /* include web2 */
	while (nlefttoread > 0) {
		while (nconn < maxnconn && nlefttoconn > 0) {
            /* 4find a file to read */
			for (i = 0 ; i < nfiles; i++)
				if (file[i].f_flags == 0)
					break;
			if (i == nfiles)
				err_quit("nlefttoconn = %d but nothing found", nlefttoconn);
			start_connect(&file[i]);
			nconn++;
			nlefttoconn--;
		}
        
        struct kevent events[2];
        
        ret = kevent(kq, NULL, 0, events, nfiles, NULL);
        
		for (i = 0; i < ret; i++) {

			//fd = file[i].f_fd;
            struct kevent event = events[i];
            //kqueue返回的events list事件是不按照顺序的。所以要根据event找到file index。这一点跟select有很大的不同,因为select是按照顺序的
            index = find_file_index_by_event(event);
			flags = file[index].f_flags;
			if (flags == 0 || flags & F_DONE)
				continue;
            
            int fd = event.ident;
            int avail_bytes = event.data;
            
            if (flags & F_CONNECTING && event.filter == EVFILT_WRITE)
            {
				n = sizeof(error);
                //todo 这里不加socklen_t就编译不通过!
                ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&n);
				if ( ret < 0 || error != 0) {
					err_ret("nonblocking connect failed for %s",
							file[index].f_name);
				}
                /* 4connection established */
				printf("connection established for %s\n", file[index].f_name);
				
                write_get_cmd(&file[index]);/* write() the GET command */
                
                
            }
            else if (flags & F_READING && event.filter == EVFILT_READ) {
                memset(buf, 0, sizeof(buf));
				if ( (n = Read(fd, buf, sizeof(buf)-1)) == 0) {
					printf("end-of-file on %s\n", file[index].f_name);
					Close(fd);
					file[index].f_flags = F_DONE;	/* clears F_READING */
                    
                    struct kevent changes[1];
                    EV_SET(&changes[0], fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
                    ret = kevent(kq, changes, 1, NULL, 0, NULL);
                    
					nconn--;
					nlefttoread--;
				} else {
                    buf[n]= '\0';
					printf("read %d bytes from %s\n", n, file[index].f_name);
                    printf("buf = %s\n", buf);
				}
			}
            
		}
	}
	exit(0);
}
Exemplo n.º 11
0
int
main(int argc, char **argv)
{
	int		i, fd, n, maxnconn, flags, error;
	char	buf[MAXLINE];
	fd_set	rs, ws;

	if (argc < 5) {
		fprintf(stderr, "usage: web <#conns> <hostname> <homepage> <file1> ...\n");
		exit(1);
	}
	maxnconn = atoi(argv[1]);

	nfiles = min(argc - 4, MAXFILES);
	for (i = 0; i < nfiles; i++) {
		file[i].f_name = argv[i + 4];
		file[i].f_host = argv[2];
		file[i].f_flags = 0;
	}
	printf("nfiles = %d\n", nfiles);

	home_page(argv[2], argv[3]);

	FD_ZERO(&rset);
	FD_ZERO(&wset);
	maxfd = -1;
	nlefttoread = nlefttoconn = nfiles;
	nconn = 0;
/* end web1 */
/* include web2 */
	while (nlefttoread > 0) {
		while (nconn < maxnconn && nlefttoconn > 0) {
				/* 4find a file to read */
			for (i = 0 ; i < nfiles; i++)
				if (file[i].f_flags == 0)
					break;
			if (i == nfiles) {
				fprintf(stderr, "nlefttoconn = %d but nothing found\n", nlefttoconn);
				exit(1);
			}
			start_connect(&file[i]);
			nconn++;
			nlefttoconn--;
		}

		rs = rset;
		ws = wset;
		if ((n = select(maxfd+1, &rs, &ws, NULL, NULL)) < 0) {
			perror("select error");
			exit(1);
		}

		for (i = 0; i < nfiles; i++) {
			flags = file[i].f_flags;
			if (flags == 0 || flags & F_DONE)
				continue;
			fd = file[i].f_fd;
			if (flags & F_CONNECTING &&
				(FD_ISSET(fd, &rs) || FD_ISSET(fd, &ws))) {
				n = sizeof(error);
				if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &n) < 0 ||
					error != 0) {
					fprintf(stderr, "nonblocking connect failed for %s: %s\n",
							file[i].f_name, strerror(errno));
				}
					/* 4connection established */
				printf("connection established for %s\n", file[i].f_name);
				FD_CLR(fd, &wset);		/* no more writeability test */
				write_get_cmd(&file[i]);/* write() the GET command */

			} else if (flags & F_READING && FD_ISSET(fd, &rs)) {
				if ( (n = read(fd, buf, sizeof(buf))) < 0) {
					perror("read error");
					exit(1);
				} else if (n == 0) {
					printf("end-of-file on %s\n", file[i].f_name);
					if (close(fd) == -1) {
						perror("close error");
						exit(1);
					}
					file[i].f_flags = F_DONE;	/* clears F_READING */
					FD_CLR(fd, &rset);
					nconn--;
					nlefttoread--;
				} else {
					printf("read %d bytes from %s\n", n, file[i].f_name);
				}
			}
		}
	}
	exit(0);
}
Exemplo n.º 12
0
/**Test for connect delay**/
int main(int argc, char *argv[])
{
    int i, fd, maxnconn, flags, error;
    socklen_t n;
    char buf[MAXLINE];

    fd_set rs, ws;
    if(argc < 5)
        err_quit("usage: web <#conns> <hostname> <homepage> <file1> ...");

    maxnconn = atoi(argv[1]);
    nfiles   = min(argc - 4, MAXFILES);

    for(i = 0; i < nfiles; i++)
    {
        file[i].f_name  = argv[i+4];
        file[i].f_host  = argv[2];
        file[i].f_flags = 0;
    }

    printf("nfiles = %d\n", nfiles);

    home_page(argv[2], argv[3]);

    FD_ZERO(&rset);
    FD_ZERO(&wset);

    maxfd = -1;
    nconn = 0;
    nlefttoread = nlefttoconn = nfiles;

    while(nlefttoread > 0)
    {
        while(nconn < maxnconn && nlefttoconn > 0)
        {
            for(i = 0; i < nfiles; i++)
            {
                if(file[i].f_flags == 0)
                    break;

                if(i == nfiles)
                    err_quit("nlefttoconn = %d but nothing found", nlefttoconn);

                start_connect(&file[i]);

                nconn++;
                nlefttoconn--;
            }
        }

        rs = rset;
        ws = wset;

        n = Select(maxfd + 1, &rs, &ws, NULL, NULL);

        for(i = 0; i < nfiles; i++)
        {
            flags = file[i].f_flags;

            if(flags == 0 || flags & F_DONE)
                continue;

            fd = file[i].f_fd;

            if(flags & F_CONNECTING && (FD_ISSET(fd, &rs) || FD_ISSET(fd, &ws)))
            {
                n = sizeof(error);
                if(getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &n) < 0 || error != 0)
                {
                    err_ret("nonblocking connect failed for %s", file[i].f_name);
                }
                printf("connection established for %s\n", file[i].f_name);
                FD_CLR(fd, &wset);
                write_get_cmd(&file[i]);
            }
            else if(flags & F_READING && FD_ISSET(fd, &rs))
            {
                if((n = read(fd, buf, sizeof(buf))) == 0)
                {
                    printf("end of file on %s\n", file[i].f_name);
                    close(fd);
                    file[i].f_flags = F_DONE;
                    FD_CLR(fd, &rset);
                    nconn--;
                    nlefttoread--;
                }
                else
                    printf("read %d bytes from %s\n", n, file[i].f_name);
            }
        }
    }
    exit(0);
}