newnew() creates a new POE::Wheel::SocketFactory object. For sockets which listen() for and accept()
connections, the wheel will generate new sockets for each accepted client. Socket factories for one-shot
sockets, such as UDP peers or clients established by connect() only emit a single socket and can be
destroyed afterwards without ill effects.
new() always returns a POE::Wheel::SocketFactory object even if it fails to establish the socket. This
allows the object to be queried after it has sent its session a "FailureEvent".
new() accepts a healthy number of named parameters, each governing some aspect of socket creation.
CreatingtheSocket
Socket creation is done with Perl's built-in socket() function. The new() parameters beginning with
"Socket" determine how socket() will be called.
SocketDomain
"SocketDomain" instructs the wheel to create a socket within a particular domain. Supported domains are
"AF_UNIX", "AF_INET", "AF_INET6", "PF_UNIX", "PF_INET", and "PF_INET6". If omitted, the socket will be
created in the "AF_INET" domain.
POE::Wheel::SocketFactory contains a table of supported domains and the instructions needed to create
them. Please send patches to support additional domains, as needed.
Note: "AF_INET6" and "PF_INET6" are supplied by the Socket module included in Perl 5.8.0 or later. Perl
versions before 5.8.0 should not attempt to use IPv6 until someone contributes a workaround.
IPv6 support requires a Socket module that implements getaddrinfo() and unpack_sockaddr_in6(). There may
be other modules that perform these functions, but most if not all of them have been deprecated with the
advent of proper core Socket support for IPv6.
SocketType
"SocketType" supplies the socket() call with a particular socket type, which may be "SOCK_STREAM" or
"SOCK_DGRAM". "SOCK_STREAM" is the default if "SocketType" is not supplied.
SocketProtocol
"SocketProtocol" sets the socket() call's protocol. Protocols may be specified by number or name.
"SocketProtocol" is ignored for UNIX domain sockets.
The protocol defaults to "tcp" for INET domain sockets. There is no default for other socket domains.
SettingSocketOptions
POE::Wheel::SocketFactory uses ioctl(), fcntl() and setsockopt() to set socket options after the socket
is created. All sockets are set non-blocking, and bound sockets may be made reusable.
Reuse
When set, the "Reuse" parameter allows a bound port to be reused immediately. "Reuse" is considered
enabled if it contains "yes", "on", or a true numeric value. All other values disable port reuse, as
does omitting "Reuse" entirely.
For security purposes, a port cannot be reused for a minute or more after a server has released it. This
gives clients time to realize the port has been abandoned. Otherwise a malicious service may snatch up
the port and spoof the legitimate service.
It's also terribly annoying to wait a minute or more between server invocations, especially during
development.
BindtheSockettoanAddressandPort
A socket may optionally be bound to a specific interface and port. The "INADDR_ANY" address may be used
to bind to a specific port across all interfaces.
Sockets are bound using bind(). POE::Wheel::SocketFactory parameters beginning with "Bind" control how
bind() is called.
BindAddress
"BindAddress" sets an address to bind the socket's local endpoint to. "INADDR_ANY" will be used if
"BindAddress" is not specified.
"BindAddress" may contain either a string or a packed Internet address (for "INET" domain sockets). The
string parameter should be a dotted numeric address or a resolvable host name. Note that the host name
will be resolved with a blocking call. If this is not desired, use POE::Component::Client::DNS to
perform a non-blocking name resolution.
When used to bind a "UNIX" domain socket, "BindAddress" should contain a path describing the socket's
filename. This is required for server sockets and datagram client sockets. "BindAddress" has no default
value for UNIX sockets.
BindPort
"BindPort" is only meaningful for "INET" domain sockets. It contains a port on the "BindAddress"
interface where the socket will be bound. It defaults to 0 if omitted, which will cause the bind() call
to choose an indeterminate unallocated port.
"BindPort" may be a port number or a name that can be looked up in the system's services (or equivalent)
database.
ConnectionlessSockets
Connectionless sockets may interact with remote endpoints without needing to listen() for connections or
connect() to remote addresses.
This class of sockets is complete after the bind() call.
ConnectingtheSockettoaRemoteEndpoint
A socket may either listen for connections to arrive, initiate connections to a remote endpoint, or be
connectionless (such as in the case of UDP sockets).
POE::Wheel::SocketFactory will initiate a client connection when new() is capped with parameters that
describe a remote endpoint. In all other cases, the socket will either listen for connections or be
connectionless depending on the socket type.
The following parameters describe a socket's remote endpoint. They determine how
POE::Wheel::SocketFactory will call Perl's built-in connect() function.
RemoteAddress
"RemoteAddress" specifies the remote address to which a socket should connect. If present,
POE::Wheel::SocketFactory will create a client socket that attempts to collect to the "RemoteAddress".
Otherwise, if the protocol warrants it, the wheel will create a listening socket and attempt to accept
connections.
As with the bind address, "RemoteAddress" may be a string containing a dotted quad or a resolvable host
name. It may also be a packed Internet address, or a UNIX socket path. It will be packed, with or
without an accompanying "RemotePort", as necessary for the socket domain.
RemotePort
"RemotePort" is the port to which the socket should connect. It is required for "INET" client sockets,
since the remote endpoint must contain both an address and a port.
The remote port may be numeric, or it may be a symbolic name found in /etc/services or the equivalent for
your operating system.
ListeningforConnections
Streaming sockets that have no remote endpoint are considered to be server sockets.
POE::Wheel::SocketFactory will listen() for connections to these sockets, accept() the new clients, and
send the application events with the new client sockets.
POE::Wheel::SocketFactory constructor parameters beginning with "Listen" control how the listen()
function is called.
ListenQueue
"ListenQueue" specifies the length of the socket's listen() queue. It defaults to "SOMAXCONN" if
omitted. "ListenQueue" values greater than "SOMAXCONN" will be clipped to "SOMAXCONN". Excessively
large "ListenQueue" values are not necessarily portable, and may cause errors in some rare cases.
EmittingEvents
POE::Wheel::SocketFactory emits a small number of events depending on what happens during socket setup or
while listening for new connections.
See "PUBLIC EVENTS" for more details.
SuccessEvent
"SuccessEvent" names the event that will be emitted whenever POE::Wheel::SocketFactory succeeds in
creating a new socket.
For connectionless sockets, "SuccessEvent" happens just after the socket is created.
For client connections, "SuccessEvent" is fired when the connection has successfully been established
with the remote endpoint.
Server sockets emit a "SuccessEvent" for every successfully accepted client.
FailureEvent
"FailureEvent" names the event POE::Wheel::SocketFactory will emit whenever something goes wrong. It
usually represents some kind of built-in function call error. See "PUBLIC EVENTS" for details, as some
errors are handled internally by this wheel.
eventevent() allows a session to change the events emitted by a wheel without destroying and re-creating the
wheel. It accepts one or more of the events listed in "PUBLIC EVENTS". Undefined event names disable
those events.
event() is described in more depth in POE::Wheel.
getsocknamegetsockname() behaves like the built-in function of the same name. It returns the local endpoint
information for POE::Wheel::SocketFactory's encapsulated listening socket.
getsockname() allows applications to determine the address and port to which POE::Wheel::SocketFactory
has bound its listening socket.
Test applications may use getsockname() to find the server socket after POE::Wheel::SocketFactory has
bound to INADDR_ANY port 0.
Since there is no event fired immediately after a successful creation of a listening socket, applications
can use getsockname() to verify this.
use Socket 'unpack_sockaddr_in';
my $listener = POE::Wheel::SocketFactory->new(
BindPort => 123,
SuccessEvent => 'got_client',
FailureEvent => 'listener_failed',
Reuse => 'on',
);
my ($port, $addr) = unpack_sockaddr_in($listener->getsockname);
print "Socket successfully bound\n" if $port;
IDID() returns the wheel's unique ID. The ID will also be included in every event the wheel generates.
Applications can match events back to the objects that generated them.
pause_accept
Applications may occasionally need to block incoming connections. pause_accept() pauses the event
watcher that triggers accept(). New inbound connections will stack up in the socket's listen() queue
until the queue overflows or the application calls resume_accept().
Pausing accept() can limit the amount of load a server generates. It's also useful in pre-forking
servers when the master process shouldn't accept connections at all.
pause_accept() and resume_accept() is quicker and more reliable than dynamically destroying and re-
creating a POE::Wheel::SocketFactory object.
resume_acceptresume_accept() resumes the watcher that triggers accept(). See "pause_accept" for a more detailed
discussion.