⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 web02.c

📁 UNIX环境下多线程的网络编程例子
💻 C
字号:
/* Doesn't work right.  Main thread sucks up all the CPU time polling unless   we call thr_yield(). */#include	"unpthread.h"#include	<thread.h>		/* Solaris threads */#define	MAXFILES	20#define	SERV		"80"	/* port number or service name */struct file {  char	*f_name;			/* filename */  char	*f_host;			/* hostname or IP address */  int    f_fd;				/* descriptor */  int	 f_flags;			/* F_xxx below */  int	 f_tid;				/* thread ID */} file[MAXFILES];#define	F_CONNECTING	1	/* connect() in progress */#define	F_READING		2	/* connect() complete; now reading */#define	F_DONE			4	/* all done */#define	F_JOINED		8	/* main has pthread_join'ed */int		nconn, nfiles, nlefttoconn, nlefttoread;char	get[] = "GET / HTTP/1.0\r\n\r\n";	/* for home page */int				ndone;		/* number of terminated threads & mutex */pthread_mutex_t	ndone_mutex = PTHREAD_MUTEX_INITIALIZER;void	*do_get_read(void *);void	home_page(const char *, const char *);void	write_get_cmd(struct file *);intmain(int argc, char **argv){	int			i, n, maxnconn;	pthread_t	tid;	struct file	*fptr;	if (argc < 5)		err_quit("usage: web <#conns> <IPaddr> <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]);	nlefttoread = nlefttoconn = nfiles;	nconn = 0;	while (nlefttoread > 0) {/* printf("nconn = %d, nlefttoconn = %d\n", nconn, nlefttoconn); */		while (nconn < maxnconn && nlefttoconn > 0) {				/* find 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);			if ( (n = pthread_create(&tid, NULL, &do_get_read, &file[i])) != 0)				errno = n, err_sys("pthread_create error");printf("created thread %d\n", tid);			file[i].f_tid = tid;			file[i].f_flags = F_CONNECTING;			nconn++;			nlefttoconn--;		}thr_yield();			/* See if one of the threads is done */		if ( (n = pthread_mutex_lock(&ndone_mutex)) != 0)			errno = n, err_sys("pthread_mutex_lock error");		if (ndone > 0) {			for (i = 0; i < nfiles; i++) {				if (file[i].f_flags & F_DONE) {					if ( (n = pthread_join(file[i].f_tid, (void **) &fptr)) != 0)						errno = n, err_sys("pthread_join error");							if (&file[i] != fptr)						err_quit("file[i] != fptr");					fptr->f_flags = F_JOINED;	/* clears F_DONE */					ndone--;					nconn--;					nlefttoread--;					printf("thread id %d for %s done\n",							file[i].f_tid, fptr->f_name);				}			}		}		if ( (n = pthread_mutex_unlock(&ndone_mutex)) != 0)			errno = n, err_sys("pthread_mutex_unlock error");	}	exit(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) {			if (n == 0)				break;		/* server closed connection */			else				err_sys("read error");		}		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 */	if ( (n = pthread_mutex_lock(&ndone_mutex)) != 0)		errno = n, err_sys("pthread_mutex_lock error");	ndone++;	if ( (n = pthread_mutex_unlock(&ndone_mutex)) != 0)		errno = n, err_sys("pthread_mutex_unlock error");	return(fptr);		/* terminate thread */}voidwrite_get_cmd(struct file *fptr){	int		n;	char	line[MAXLINE];	strcpy(line, "GET ");	strcat(line, fptr->f_name);	strcat(line, " HTTP/1.0\r\n\r\n");	n = strlen(line);	if (writen(fptr->f_fd, line, n) != n)		err_sys("writen error");	printf("wrote %d bytes for %s\n", n, fptr->f_name);	fptr->f_flags = F_READING;			/* clears F_CONNECTING */}voidhome_page(const char *host, const char *fname){	int					fd, n;	char				line[MAXLINE];	fd = Tcp_connect(host, SERV);	strcpy(line, "GET ");	strcat(line, fname);	strcat(line, " HTTP/1.0\r\n\r\n");	n = strlen(line);	if (writen(fd, line, n) != n)		err_sys("writen error");	for ( ; ; ) {		if ( (n = read(fd, line, MAXLINE)) <= 0) {			if (n == 0)				break;		/* server closed connection */			else				err_sys("read error");		}		printf("read %d bytes of home page\n", n);		/* do whatever with data */	}	printf("end-of-file on home page\n");	close(fd);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -