readhandler.cpp

来自「ace开发环境 用来开发网络程序 其运用了设计模式、多平台、C++等多种知识」· C++ 代码 · 共 152 行

CPP
152
字号
/* * ACE reactor demonstration * * $Id: ReadHandler.cpp 71351 2006-03-01 23:48:42Z shuston $ * Date: 26-Jan-2006 */#include <ace/streams.h>#include <ace/Time_Value.h>#include "common.h"#include "ReadHandler.h"/** * This macro is used to increase the invocation counter by one when entering * handle_input(). It also checks wether the counter is greater than zero * indicating, that handle_input() has been called before. */#define INVOCATION_ENTER() do { if (mInvocationCounter > 0) \        ACE_ERROR((LM_ERROR, ACE_TEXT("Multiple invocations detected.\n"))); \        mInvocationCounter++; } while (0)/** * THis macro is the counter part to INVOCATION_ENTER(). It decreases the * invocation counter and then returns the given value. This macro is * here for convenience to decrease the invocation counter also when returning * due to errors. */#define INVOCATION_RETURN(retval) do { mInvocationCounter--; \                                    return retval; } while(0)ReadHandler::ReadHandler() : ACE_Event_Handler(), mStream(), mDataSize(0),        mData(0), mCallCounter(0), mInvocationCounter(0) {    ACE_TRACE(ACE_TEXT("ReadHandler::ReadHandler()"));}ReadHandler::~ReadHandler() {    ACE_TRACE(ACE_TEXT("ReadHandler::~ReadHandler()"));    if (mStream.close() == -1)      ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to close socket. ")                 ACE_TEXT ("(errno = %i: %m)\n"), errno));    delete[] mData;}ACE_SOCK_Stream &ReadHandler::getStream(void) {    ACE_TRACE(ACE_TEXT("ReadHandler::getStream(void)"));    return mStream;}ACE_HANDLE ReadHandler::get_handle(void) const {    ACE_TRACE(ACE_TEXT("ReadHandler::get_handle(void)"));    return mStream.get_handle();}int ReadHandler::handle_input(ACE_HANDLE) {    ACE_TRACE(ACE_TEXT("ReadHandler::handle_input(ACE_HANDLE)"));    INVOCATION_ENTER();    // the response sent to the client    char response = 0;    if (mCallCounter == 0) {        /*         * This is the first request from the client.         */        // increase the call counter so the next client request goes to else-if        mCallCounter++;        // get the desired size from the client        // Note: only use the sizeof and pointer to int on compatible        //       platforms (i.e. little-endian/big-endian, data type size)        if (mStream.recv_n(&mDataSize, sizeof(mDataSize),                &connTimeout) != sizeof(mDataSize)) {          ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to receive ")                     ACE_TEXT ("request. (errno = %i: %m)\n"), errno));            INVOCATION_RETURN(-1);        }        // The verbose debug output is replaced with some unintrusive dots.        // This increases visibility of the desired effect.        // ACE_DEBUG((LM_DEBUG, ACE_TEXT("%@: Data size: %i\n"), this, mDataSize));        ACE_DEBUG((LM_DEBUG, ACE_TEXT(".")));        // check mDataSize for plausability then allocate memory        if (mDataSize > 0) {            mData = new (std::nothrow) char[mDataSize];            if (mData == 0)              ACE_DEBUG((LM_DEBUG, ACE_TEXT("%N:%l: Failed to allocate ")                         ACE_TEXT ("data buffer.\n")));            else                response = 'K';        }        // send the response to the client (which is still 0, if the        // allocation did not succeed)        if (mStream.send_n(&response, sizeof(response), &connTimeout) != 1) {          ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to send ")                     ACE_TEXT ("response. (errno = %i: %m)\n"), errno));            INVOCATION_RETURN(-1);        }        if (response == 'K')            INVOCATION_RETURN(0); // get another request from the same client        else            INVOCATION_RETURN(-1); // the client will not send data if response != 'K'    } else if (mCallCounter == 1) {        /*         * This is the second request from the client.         */        // increase the call counter, this read handler should not be called        // again        mCallCounter++;        // receive the data from the client        if (mStream.recv_n(mData, mDataSize, &connTimeout) != mDataSize) {          ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to receive data.")                     ACE_TEXT ("(errno = %i: %m)\n"), errno));            INVOCATION_RETURN(-1);        }        response = 'K';        if (mStream.send_n(&response, 1, &connTimeout) != 1) {          ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to send ")                     ACE_TEXT ("confirmation. (errno = %i: %m)\n"), errno));            INVOCATION_RETURN(-1);        }        INVOCATION_RETURN(-1); // ask for removal, since client does not send any more data    }    // this is to find strange actions with the call counter    ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: We should not get here.")));    INVOCATION_RETURN(-1);}int ReadHandler::handle_close(ACE_HANDLE, ACE_Reactor_Mask) {  ACE_TRACE("ReadHandler::handle_close(ACE_HANDLE, ACE_Reactor_Mask)");    delete this;    return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?