/usr/include/Poco/Net/SocketConnector.h is in libpoco-dev 1.8.0.1-1ubuntu4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | //
// SocketConnector.h
//
// Library: Net
// Package: Reactor
// Module: SocketConnector
//
// Definition of the SocketConnector class.
//
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Net_SocketConnector_INCLUDED
#define Net_SocketConnector_INCLUDED
#include "Poco/Net/Net.h"
#include "Poco/Net/SocketNotification.h"
#include "Poco/Net/SocketAddress.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Observer.h"
namespace Poco {
namespace Net {
template <class ServiceHandler>
class SocketConnector
/// This class implements the Connector part of the
/// Acceptor-Connector design pattern.
///
/// The Acceptor-Connector pattern has been described in the book
/// "Pattern Languages of Program Design 3", edited by Robert Martin,
/// Frank Buschmann and Dirk Riehle (Addison Wesley, 1997).
///
/// The Acceptor-Connector design pattern decouples connection
/// establishment and service initialization in a distributed system
/// from the processing performed once a service is initialized.
/// This decoupling is achieved with three components: Acceptors,
/// Connectors and Service Handlers.
/// The Connector actively establishes a connection with a remote
/// server socket (usually managed by an Acceptor) and initializes
/// a Service Handler to manage the connection.
///
/// The SocketConnector sets up a StreamSocket, initiates a non-blocking
/// connect operation and registers itself for ReadableNotification, WritableNotification
/// and ErrorNotification. ReadableNotification or WritableNotification denote the successful
/// establishment of the connection.
///
/// When the StreamSocket becomes readable or writeable, the SocketConnector
/// creates a ServiceHandler to service the connection and unregisters
/// itself.
///
/// In case of an error (ErrorNotification), the SocketConnector unregisters itself
/// and calls the onError() method, which can be overridden by subclasses
/// to perform custom error handling.
///
/// The ServiceHandler class must provide a constructor that
/// takes a StreamSocket and a SocketReactor as arguments,
/// e.g.:
/// MyServiceHandler(const StreamSocket& socket, ServiceReactor& reactor)
///
/// When the ServiceHandler is done, it must destroy itself.
///
/// Subclasses can override the createServiceHandler() factory method
/// if special steps are necessary to create a ServiceHandler object.
{
public:
explicit SocketConnector(SocketAddress& address):
_pReactor(0)
/// Creates a SocketConnector, using the given Socket.
{
_socket.connectNB(address);
}
SocketConnector(SocketAddress& address, SocketReactor& reactor):
_pReactor(0)
/// Creates an acceptor, using the given ServerSocket.
/// The SocketConnector registers itself with the given SocketReactor.
{
_socket.connectNB(address);
registerConnector(reactor);
}
virtual ~SocketConnector()
/// Destroys the SocketConnector.
{
try
{
unregisterConnector();
}
catch (...)
{
poco_unexpected();
}
}
virtual void registerConnector(SocketReactor& reactor)
/// Registers the SocketConnector with a SocketReactor.
///
/// A subclass can override this and, for example, also register
/// an event handler for a timeout event.
///
/// The overriding method must call the baseclass implementation first.
{
_pReactor = &reactor;
_pReactor->addEventHandler(_socket, Poco::Observer<SocketConnector, ReadableNotification>(*this, &SocketConnector::onReadable));
_pReactor->addEventHandler(_socket, Poco::Observer<SocketConnector, WritableNotification>(*this, &SocketConnector::onWritable));
_pReactor->addEventHandler(_socket, Poco::Observer<SocketConnector, ErrorNotification>(*this, &SocketConnector::onError));
}
virtual void unregisterConnector()
/// Unregisters the SocketConnector.
///
/// A subclass can override this and, for example, also unregister
/// its event handler for a timeout event.
///
/// The overriding method must call the baseclass implementation first.
{
if (_pReactor)
{
_pReactor->removeEventHandler(_socket, Poco::Observer<SocketConnector, ReadableNotification>(*this, &SocketConnector::onReadable));
_pReactor->removeEventHandler(_socket, Poco::Observer<SocketConnector, WritableNotification>(*this, &SocketConnector::onWritable));
_pReactor->removeEventHandler(_socket, Poco::Observer<SocketConnector, ErrorNotification>(*this, &SocketConnector::onError));
}
}
void onReadable(ReadableNotification* pNotification)
{
pNotification->release();
int err = _socket.impl()->socketError();
if (err)
{
onError(err);
unregisterConnector();
}
else
{
onConnect();
}
}
void onWritable(WritableNotification* pNotification)
{
pNotification->release();
onConnect();
}
void onConnect()
{
_socket.setBlocking(true);
createServiceHandler();
unregisterConnector();
}
void onError(ErrorNotification* pNotification)
{
pNotification->release();
onError(_socket.impl()->socketError());
unregisterConnector();
}
protected:
virtual ServiceHandler* createServiceHandler()
/// Create and initialize a new ServiceHandler instance.
///
/// Subclasses can override this method.
{
return new ServiceHandler(_socket, *_pReactor);
}
virtual void onError(int errorCode)
/// Called when the socket cannot be connected.
///
/// Subclasses can override this method.
{
}
SocketReactor* reactor()
/// Returns a pointer to the SocketReactor where
/// this SocketConnector is registered.
///
/// The pointer may be null.
{
return _pReactor;
}
StreamSocket& socket()
/// Returns a reference to the SocketConnector's socket.
{
return _socket;
}
private:
SocketConnector();
SocketConnector(const SocketConnector&);
SocketConnector& operator = (const SocketConnector&);
StreamSocket _socket;
SocketReactor* _pReactor;
};
} } // namespace Poco::Net
#endif // Net_SocketConnector_INCLUDED
|