client.cpp 文件 #include "unpthread.h" #define MAXFILES 20 #define SERV "80" struct file{ char *f_name ; char *f_host ; int f_fd ; int f_flags ; pthread_t f_tid ; }file[MAXFILES]; #define F_CONNECTING 1 #define F_READING 2 #define F_DONE 4 #define GET_CMD "GET %s HTTP/1.0\r\n\r\n" #define F_JOINED 8 int ndone ; pthread_mutex_t ndone_mutex = PTHREAD_MUTEX_INITIALIZER ; pthread_cond_t ndone_cond = PTHREAD_COND_INITIALIZER ; int nconn , nfiles , nlefttoconn , nlefttoread ; void *do_get_read(void *); void home_page(const char * , const char *); void write_get_cmd(struct file *); /*主线程处理*/ int main(int argc , char **argv){ int i , n , maxnconn ; pthread_t tid ; struct file *fptr ; if(argc < 5) throw runtime_error("usage : client <#conns> <IPaddr> <home_page> 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 ; } cout << "nfiles = "<<nfiles <<endl; home_page(argv[2] , argv[3]); nlefttoconn = nlefttoread = nfiles ; nconn = 0 ; while(nlefttoread > 0){ while(nconn < maxnconn && nlefttoconn > 0){ for( i = 0 ; i < nfiles ; i ++) if(file[i].f_flags == 0 ) break; if( i == nfiles) throw runtime_error("nothing to connect"); file[i].f_flags = F_CONNECTING ; pthread_create(&tid , NULL , &do_get_read , &file[i]); file[i].f_tid = tid ; nconn ++ ; nlefttoconn -- ; } pthread_mutex_lock(&ndone_mutex); while(ndone == 0 ) pthread_cond_wait(&ndone_cond , &ndone_mutex) ; for( i = 0 ; i < nfiles ; i++){ if(file[i].f_flags & F_DONE){ /*等待线程终止*/ pthread_join(file[i].f_tid , (void **)&fptr); if(&file[i] != fptr ) throw runtime_error("file[i] != fptr"); fptr->f_flags = F_JOINED ; ndone -- ; nconn -- ; nlefttoread -- ; cout << "thread ID: "<< fptr->f_tid << " name : " << fptr->f_name<<endl; } } pthread_mutex_unlock(&ndone_mutex); } return 0; } int Tcp_connect(const char * host , const char *serv){ int fd , n ; struct addrinfo hints , *res , *ressave ; bzero(&hints , sizeof(hints)); hints.ai_socktype = SOCK_STREAM ; hints.ai_family = AF_UNSPEC ; if(getaddrinfo(host , serv , &hints , &res) != 0 ) throw runtime_error("getaddrinfo error"); ressave = res ; do{ fd = socket(res->ai_family , res->ai_socktype ,res->ai_protocol); if(fd < 0 ) continue ; if(connect(fd , res->ai_addr , res->ai_addrlen) == 0) break; //链接成功,跳出循环 close(fd) ; }while( (res = res->ai_next)) ; if(res == NULL) throw runtime_error("scoket error"); freeaddrinfo(ressave); return fd ; } /*线程执行函数*/ 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 ; cout << "read " << fptr->f_name << "; fd : " << fptr->f_fd << "; thread ID :" << fptr->f_tid<<endl; write_get_cmd(fptr); while(true){ if( (n = read(fd , line , MAXLINE) ) == 0) break; cout << "read " << n << " bytes from " << fptr->f_name<<endl; } cout << "end-of-file on " << fptr->f_name<<endl; close(fd); pthread_mutex_lock(&ndone_mutex); fptr->f_flags = F_DONE ; ndone ++ ; pthread_cond_signal(&ndone_cond); pthread_mutex_unlock(&ndone_mutex); return fptr ; } void home_page(const char *host , const char *fname ) { int fd , n ; char recv[MAXLINE] ; fd = Tcp_connect(host , SERV); n = snprintf(recv , sizeof(recv) , GET_CMD , fname); while(write(fd , recv , n ) == 0 ) continue ; while(true){ if( (n = read(fd , recv , MAXLINE )) == 0 ) break; cout << "read " << n << " bytes from home_page. " <<endl; } cout << "end-of-home_page"<<endl; cout << "------------------------------------"<<endl; close(fd); } void write_get_cmd(struct file *fptr){ int n ; char line[MAXLINE] ; n = snprintf(line , sizeof(line) , GET_CMD , fptr->f_name); while(write(fptr->f_fd , line , n ) == 0) continue ; cout << "wrote " << n << " from " << fptr->f_name<<endl; fptr->f_flags = F_READING ; } unp.h头文件
#include <pthread.h> #include <iostream> #include <exception> #include <stdexcept> #include <string> #include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <sys/un.h> #include <netdb.h> #include <stdlib.h> #include <cstdio> #define MAXLINE 4096 using namespace std;
WEB客户与同时链接
最新推荐文章于 2019-04-20 23:56:58 发布