readhandler.cpp
来自「最新的版本ACE-5.6.8,刚从外文网上搬下,与大家分享.」· C++ 代码 · 共 153 行
CPP
153 行
/*
* ACE reactor demonstration
*
* $Id: ReadHandler.cpp 80826 2008-03-04 14:51:23Z wotte $
* Date: 26-Jan-2006
*/
#include "common.h"
#include "ReadHandler.h"
#include <ace/streams.h>
#include <ace/Time_Value.h>
#include <ace/Log_Msg.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 + -
显示快捷键?