TCP预先派生子进程服务器模型-客户端测试程序
今天对测试用的客户端程序做了一点修改,以便于更好分析测试结果!
/********************************************************************
* 文件名称: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;
}
阅读(568) | 评论(0) | 转发(0) |