/******************************************************************** * 文件名称:client.c * 摘 要:TCP预先派生子进程服务器模型-客户端测试程序 * * 当前版本:0.2 * 作 者:Allen Yao * 电子邮件:ihave6630@163.com * 完成日期:2008年12月3日 * * 更新日期:2008年12月3日 * 更新内容:(1) 增加日志记录功能,替代屏幕打印,便于记录测试结果。 * (2) 增加计时器功能,便于统计每个子进程从启动到结束所消耗 * 的时间。 ********************************************************************/ #include <sys/types.h> #include <sys/wait.h> #include <sys/socket.h> #include <arpa/inet.h> #include <stdarg.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/time.h> #include <time.h> /* #define DEBUG 测试时打开*/
#define MAXLINE 256 #define MAXN 16384 /* max #bytes to request from server */
struct timeval starttime,endtime; int timeuse; int elapsedtime( void ); int tcp_connect( char *pAddr, int nPort ); ssize_t readn( int fd, void *vptr, size_t n ); ssize_t writen( int fd, void *vptr, size_t n ); void file_log( char *format, ... );
/*****************************************************************************/ /* */ /*****************************************************************************/ int main( int argc, char *argv[] ) { int i, fd, nchildren, nbytes; pid_t pid; ssize_t n; char request[MAXLINE], reply[MAXN]; if (argc != 5) { printf( "usage: client <#children> <#bytes/request>\n" ); exit( 1 ); } nchildren = atoi( argv[3] ); nbytes = atoi( argv[4] ); snprintf( request, sizeof(request), "%d", nbytes );
file_log( "\n\n测试数据:子进程个数[%d] 读取字节数[%d]", nchildren, nbytes );
for (i=0; i<nchildren; i++) { if ((pid=fork()) == 0) { gettimeofday( &starttime, NULL );
fd = tcp_connect( argv[1], atoi(argv[2]) ); if (fd < 0) { file_log( "connect server returned %d", fd ); } #ifdef DEBUG file_log( "子进程[%4d] : 连接服务器端成功", i ); #endif writen( fd, request, strlen(request) ); #ifdef DEBUG file_log( "子进程[%4d] : 发送数据:[%s]", i, request ); #endif memset( reply, 0x00, sizeof(reply) );
if ((n = readn( fd, reply, nbytes )) != nbytes) { file_log( "server returned %d bytes", n ); } #ifdef DEBUG file_log( "子进程[%4d] : 接收数据:[%s]", i, reply ); #endif close( fd );/* TIME_WAIT on client, not server */ file_log( "子进程[%4d] : 运行结束 耗时[%10d]微秒", i, elapsedtime() ); exit( 0 ); } /* parent loops around to fork() again */ } while(wait(NULL) > 0) /* now parent waits for all children */ ; if (errno != ECHILD) { printf( "wait error" ); } exit( 0 ); }
/*****************************************************************************/ /* */ /*****************************************************************************/ int tcp_connect( char *pAddr, int nPort ) { struct sockaddr_in addrin; int nSocket; if ((pAddr == NULL) || (nPort <= 0)) { return -1; } nSocket = socket( AF_INET, SOCK_STREAM, 0 ); if (nSocket < 0) { return -2; } memset( &addrin, 0x00, sizeof(addrin) ); addrin.sin_family = AF_INET; addrin.sin_addr.s_addr = inet_addr( pAddr ); addrin.sin_port = htons( nPort ); if (connect( nSocket, (struct sockaddr *)&addrin, sizeof(addrin) ) != 0) { close( nSocket ); return -3; } return nSocket; }
/*****************************************************************************/ /* */ /*****************************************************************************/ ssize_t readn( int fd, void *vptr, size_t n ) { ssize_t nleft; ssize_t nread; char *ptr;
ptr = vptr; nleft = n; while(nleft > 0) { if ((nread = read(fd, ptr, nleft)) < 0) { if (errno == EINTR) { nread = 0; /* and call read() again */ } else { return(-1); } } else if (nread == 0) { break; /* EOF */ } nleft -= nread; ptr += nread; } return(n - nleft); /* return >= 0 */ }
/*****************************************************************************/ /* */ /*****************************************************************************/ ssize_t writen( int fd, void *vptr, size_t n ) { ssize_t nleft; ssize_t nwritten; const char *ptr;
ptr = vptr; nleft = n; while(nleft > 0) { if ((nwritten = write(fd, ptr, nleft)) <= 0) { if (errno == EINTR) { nwritten = 0; /* and call write() again */ } else { return(-1); /* error */ } } nleft -= nwritten; ptr += nwritten; } return(n); }
/*****************************************************************************/ /* */ /*****************************************************************************/ void file_log( char *format, ... ) { va_list ap; struct tm *p; time_t t; char szLogFile[256]; FILE *fp;
t = time( NULL ); p = localtime( &t ); memset( szLogFile, 0x00, sizeof(szLogFile) ); sprintf( szLogFile, "%s.20%02d%02d%02d", "client", p->tm_year%100,p->tm_mon+1,p->tm_mday); if((fp = fopen(szLogFile, "a"))==NULL) { printf( "fopen() error: LogFileName:[%s]", szLogFile ); return ; } fprintf( fp, "20%02d/%02d/%02d %02d:%02d:%02d [%-7d]: ", p->tm_year%100,p->tm_mon+1,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec,getpid()); va_start( ap, format ); vfprintf( fp, format, ap ); fprintf( fp, "\n" ); fflush( fp ); fclose( fp ); return; }
/*****************************************************************************/ /* */ /*****************************************************************************/ int elapsedtime( void ) { gettimeofday( &endtime, NULL ); timeuse = 1000000 * ( endtime.tv_sec - starttime.tv_sec ) + endtime.tv_usec - starttime.tv_usec; return timeuse; }
|