📄 teststress.cpp
字号:
/* * Copyright 2007 Stephen Liu * For license terms, see the file COPYING along with this library. */#include <signal.h>#include <stdio.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <time.h>#include <string.h>#include <sys/socket.h>#include <netinet/in.h>/* For inet_ntoa. */#include <arpa/inet.h>#include "config.h"#include "event.h"static const char * gHost = "127.0.0.1";static int gPort = 5555;static int gMsgs = 10;static int gClients = 10;static time_t gStartTime = 0;struct SP_TestClient { int mFd; struct event mReadEvent; struct event mWriteEvent; int mSendMsgs; int mRecvMsgs; char mBuffer[ 512 ];};void showUsage( const char * program ){ printf( "Stress Test Tools for spserver example -- testchat\n" ); printf( "Usage: %s [-h <host>] [-p <port>] [-c <clients>] [-m <messages>]\n", program ); printf( "\t-h default is %s\n", gHost ); printf( "\t-p default is %d\n", gPort ); printf( "\t-c how many clients, default is %d\n", gClients ); printf( "\t-m messages per client, default is %d\n", gMsgs ); printf( "\n" );}void close_read( SP_TestClient * client ){ //fprintf( stderr, "#%d close read\n", client->mFd ); event_del( &client->mReadEvent ); gClients--;}void close_write( SP_TestClient * client ){ //fprintf( stderr, "#%d close write\n", client->mFd ); event_del( &client->mWriteEvent );}void close_client( SP_TestClient * client ){ close_write( client ); close_read( client );}void on_read( int fd, short events, void *arg ){ SP_TestClient * client = ( SP_TestClient * ) arg; if( EV_READ & events ) { int len = read( fd, client->mBuffer, sizeof( client->mBuffer ) ); if( len <= 0 ) { if( len < 0 && EINTR != errno && EAGAIN != errno ) { fprintf( stderr, "#%d on_read error\n", fd ); } close_client( client ); } else { for( int i = 0; i < len; i++ ) { //if( 10 == fd ) printf( "%c", client->mBuffer[i] ); if( '\n' == client->mBuffer[i] ) client->mRecvMsgs++; } } } else { fprintf( stderr, "#%d on_read timeout\n", fd ); close_client( client ); }}void on_write( int fd, short events, void *arg ){ SP_TestClient * client = ( SP_TestClient * ) arg; if( EV_WRITE & events ) { client->mSendMsgs++; if( client->mSendMsgs >= gMsgs ) { snprintf( client->mBuffer, sizeof( client->mBuffer ), "quit\r\n" ); } else { snprintf( client->mBuffer, sizeof( client->mBuffer ), "mail #%d, It's good to see how people hire; " "that tells us how to market ourselves to them.\r\n", client->mSendMsgs ); } int len = write( fd, client->mBuffer, strlen( client->mBuffer ) ); if( len <= 0 && EINTR != errno && EAGAIN != errno ) { fprintf( stderr, "#%d on_write error\n", fd ); close_client( client ); } else { if( client->mSendMsgs >= gMsgs ) close_write( client ); } } else { fprintf( stderr, "#%d on_write timeout\n", fd ); close_client( client ); }}int main( int argc, char * argv[] ){ extern char *optarg ; int c ; while( ( c = getopt ( argc, argv, "h:p:c:m:v" )) != EOF ) { switch ( c ) { case 'h' : gHost = optarg; break; case 'p': gPort = atoi( optarg ); break; case 'c' : gClients = atoi ( optarg ); break; case 'm' : gMsgs = atoi( optarg ); break; case 'v' : case '?' : showUsage( argv[0] ); exit( 0 ); } } signal( SIGPIPE, SIG_IGN ); event_init(); SP_TestClient * clientList = (SP_TestClient*)calloc( gClients, sizeof( SP_TestClient ) ); struct sockaddr_in sin; memset( &sin, 0, sizeof(sin) ); sin.sin_family = AF_INET; sin.sin_addr.s_addr = inet_addr( gHost ); sin.sin_port = htons( gPort ); int totalClients = gClients; printf( "Create %d connections to server, it will take some minutes to complete.\n", gClients ); for( int i = 0; i < gClients; i++ ) { SP_TestClient * client = clientList + i; client->mFd = socket( AF_INET, SOCK_STREAM, 0 ); if( client->mFd < 0 ) { fprintf(stderr, "socket failed\n"); return -1; } if( connect( client->mFd, (struct sockaddr *)&sin, sizeof(sin) ) != 0) { fprintf(stderr, "connect failed\n"); return -1; } event_set( &client->mWriteEvent, client->mFd, EV_WRITE | EV_PERSIST, on_write, client ); event_add( &client->mWriteEvent, NULL ); event_set( &client->mReadEvent, client->mFd, EV_READ | EV_PERSIST, on_read, client ); event_add( &client->mReadEvent, NULL ); if( 0 == ( i % 10 ) ) write( fileno( stdout ), ".", 1 ); } time( &gStartTime ); struct timeval startTime, stopTime; struct timezone startZone, stopZone; gettimeofday( &startTime, &startZone ); time_t lastInfoTime = time( NULL ); // start event loop until all clients are exit while( gClients > 0 ) { event_loop( EVLOOP_ONCE ); if( time( NULL ) - lastInfoTime > 5 ) { time( &lastInfoTime ); printf( "waiting for %d client(s) to exit\n", gClients ); } } gettimeofday( &stopTime, &stopZone ); // show result printf( "\n\nTest result :\n" ); printf( "Clients : %d, Messages Per Client : %d\n", totalClients, gMsgs ); printf( "ExecTimes: %.6f seconds\n\n", (double) ( 1000000 * ( stopTime.tv_sec - startTime.tv_sec ) + ( stopTime.tv_usec - startTime.tv_usec ) ) / 1000000 ); printf( "client\tSend\tRecv\n" ); int totalSend = 0, totalRecv = 0; for( int i = 0; i < totalClients; i++ ) { SP_TestClient * client = clientList + i; //printf( "client#%d : %d\t%d\n", i, client->mSendMsgs, client->mRecvMsgs ); totalSend += client->mSendMsgs; totalRecv += client->mRecvMsgs; close( client->mFd ); } printf( "total : %d\t%d\n", totalSend, totalRecv ); free( clientList ); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -