提交 38524e312883be38743459b34e4811e626c05d53

作者 LJH 李佳桓
1 个父辈 314c9006

add

  1 +/*
  2 + * Copyright 2007 Stephen Liu
  3 + * For license terms, see the file COPYING along with this library.
  4 + */
  5 +
  6 +#include <stdio.h>
  7 +#include <syslog.h>
  8 +#include <string.h>
  9 +#include <unistd.h>
  10 +#include <time.h>
  11 +
  12 +#include <sys/types.h>
  13 +#include <sys/socket.h>
  14 +#include <netinet/in.h>
  15 +
  16 +#include "spdispatcher.hpp"
  17 +#include "sphandler.hpp"
  18 +#include "spresponse.hpp"
  19 +#include "sprequest.hpp"
  20 +#include "spbuffer.hpp"
  21 +#include "spmsgdecoder.hpp"
  22 +#include "speventcb.hpp"
  23 +#include "spioutils.hpp"
  24 +
  25 +class SP_EchoHandler : public SP_Handler {
  26 +public:
  27 + SP_EchoHandler(){}
  28 + virtual ~SP_EchoHandler(){}
  29 +
  30 + // return -1 : terminate session, 0 : continue
  31 + virtual int start( SP_Request * request, SP_Response * response ) {
  32 + request->setMsgDecoder( new SP_LineMsgDecoder() );
  33 + response->getReply()->getMsg()->append(
  34 + "Welcome to line echo dispatcher, enter 'quit' to quit.\r\n" );
  35 +
  36 + return 0;
  37 + }
  38 +
  39 + // return -1 : terminate session, 0 : continue
  40 + virtual int handle( SP_Request * request, SP_Response * response ) {
  41 + SP_LineMsgDecoder * decoder = (SP_LineMsgDecoder*)request->getMsgDecoder();
  42 +
  43 + if( 0 != strcasecmp( (char*)decoder->getMsg(), "quit" ) ) {
  44 + response->getReply()->getMsg()->append( (char*)decoder->getMsg() );
  45 + response->getReply()->getMsg()->append( "\r\n" );
  46 + return 0;
  47 + } else {
  48 + response->getReply()->getMsg()->append( "Byebye\r\n" );
  49 + return -1;
  50 + }
  51 + }
  52 +
  53 + virtual void error( SP_Response * response ) {}
  54 +
  55 + virtual void timeout( SP_Response * response ) {}
  56 +
  57 + virtual void close() {}
  58 +};
  59 +
  60 +class SP_EchoTimerHandler : public SP_TimerHandler {
  61 +public:
  62 + SP_EchoTimerHandler(){
  63 + mCount = 1;
  64 + }
  65 +
  66 + virtual ~SP_EchoTimerHandler(){}
  67 +
  68 + // return -1 : terminate timer, 0 : continue
  69 + virtual int handle( SP_Response * response, struct timeval * timeout ) {
  70 + syslog( LOG_NOTICE, "time = %li, call timer handler", time( NULL ) );
  71 +
  72 + if( ++mCount >= 10 ) {
  73 + syslog( LOG_NOTICE, "stop timer" );
  74 + return -1;
  75 + } else {
  76 + syslog( LOG_NOTICE, "set timer to %d seconds later", mCount );
  77 + timeout->tv_sec = mCount;
  78 + return 0;
  79 + }
  80 + }
  81 +
  82 +private:
  83 + int mCount;
  84 +};
  85 +
  86 +int main( int argc, char * argv[] )
  87 +{
  88 + int port = 3333, maxThreads = 10;
  89 +
  90 + extern char *optarg ;
  91 + int c ;
  92 +
  93 + while( ( c = getopt ( argc, argv, "p:t:v" )) != EOF ) {
  94 + switch ( c ) {
  95 + case 'p' :
  96 + port = atoi( optarg );
  97 + break;
  98 + case 't':
  99 + maxThreads = atoi( optarg );
  100 + break;
  101 + case '?' :
  102 + case 'v' :
  103 + printf( "Usage: %s [-p <port>] [-t <threads>]\n", argv[0] );
  104 + exit( 0 );
  105 + }
  106 + }
  107 +
  108 + openlog( "testdispatcher", LOG_CONS | LOG_PID | LOG_PERROR, LOG_USER );
  109 +
  110 + int maxConnections = 100, reqQueueSize = 10;
  111 + const char * refusedMsg = "System busy, try again later.";
  112 +
  113 + int listenFd = -1;
  114 + if( 0 == SP_IOUtils::tcpListen( "", port, &listenFd ) ) {
  115 + SP_Dispatcher dispatcher( new SP_DefaultCompletionHandler(), maxThreads );
  116 + dispatcher.dispatch();
  117 +
  118 + struct timeval timeout;
  119 + memset( &timeout, 0, sizeof( timeout ) );
  120 + timeout.tv_sec = 1;
  121 +
  122 + dispatcher.push( &timeout, new SP_EchoTimerHandler() );
  123 +
  124 + for( ; ; ) {
  125 + struct sockaddr_in addr;
  126 + socklen_t socklen = sizeof( addr );
  127 + int fd = accept( listenFd, (struct sockaddr*)&addr, &socklen );
  128 +
  129 + if( fd > 0 ) {
  130 + if( dispatcher.getSessionCount() >= maxConnections
  131 + || dispatcher.getReqQueueLength() >= reqQueueSize ) {
  132 + write( fd, refusedMsg, strlen( refusedMsg ) );
  133 + close( fd );
  134 + } else {
  135 + dispatcher.push( fd, new SP_EchoHandler() );
  136 + }
  137 + } else {
  138 + break;
  139 + }
  140 + }
  141 + }
  142 +
  143 + closelog();
  144 +
  145 + return 0;
  146 +}
  147 +
... ...
注册登录 后发表评论