1POE::Wheel::SocketFactoUrsye(r3)Contributed Perl DocumenPtOaEt:i:oWnheel::SocketFactory(3)
2
3
4

NAME

6       POE::Wheel::SocketFactory - non-blocking socket creation
7

SYNOPSIS

9       See "SYNOPSIS" in POE::Component::Server::TCP for a much simpler
10       version of this program.
11
12         #!perl
13
14         use warnings;
15         use strict;
16
17         use IO::Socket;
18         use POE qw(Wheel::SocketFactory Wheel::ReadWrite);
19
20         POE::Session->create(
21           inline_states => {
22             _start => sub {
23               # Start the server.
24               $_[HEAP]{server} = POE::Wheel::SocketFactory->new(
25                 BindPort => 12345,
26                 SuccessEvent => "on_client_accept",
27                 FailureEvent => "on_server_error",
28               );
29             },
30             on_client_accept => sub {
31               # Begin interacting with the client.
32               my $client_socket = $_[ARG0];
33               my $io_wheel = POE::Wheel::ReadWrite->new(
34                 Handle => $client_socket,
35                 InputEvent => "on_client_input",
36                 ErrorEvent => "on_client_error",
37               );
38               $_[HEAP]{client}{ $io_wheel->ID() } = $io_wheel;
39             },
40             on_server_error => sub {
41               # Shut down server.
42               my ($operation, $errnum, $errstr) = @_[ARG0, ARG1, ARG2];
43               warn "Server $operation error $errnum: $errstr\n";
44               delete $_[HEAP]{server};
45             },
46             on_client_input => sub {
47               # Handle client input.
48               my ($input, $wheel_id) = @_[ARG0, ARG1];
49               $input =~ tr[a-zA-Z][n-za-mN-ZA-M]; # ASCII rot13
50               $_[HEAP]{client}{$wheel_id}->put($input);
51             },
52             on_client_error => sub {
53               # Handle client error, including disconnect.
54               my $wheel_id = $_[ARG3];
55               delete $_[HEAP]{client}{$wheel_id};
56             },
57           }
58         );
59
60         POE::Kernel->run();
61         exit;
62

DESCRIPTION

64       POE::Wheel::SocketFactory creates sockets upon demand.  It can create
65       connectionless UDP sockets, but it really shines for client/server work
66       where establishing connections normally would block.
67

PUBLIC METHODS

69   new
70       new() creates a new POE::Wheel::SocketFactory object.  For sockets
71       which listen() for and accept() connections, the wheel will generate
72       new sockets for each accepted client.  Socket factories for one-shot
73       sockets, such as UDP peers or clients established by connect() only
74       emit a single socket and can be destroyed afterwards without ill
75       effects.
76
77       new() always returns a POE::Wheel::SocketFactory object even if it
78       fails to establish the socket.  This allows the object to be queried
79       after it has sent its session a "FailureEvent".
80
81       new() accepts a healthy number of named parameters, each governing some
82       aspect of socket creation.
83
84       Creating the Socket
85
86       Socket creation is done with Perl's built-in socket() function.  The
87       new() parameters beginning with "Socket" determine how socket() will be
88       called.
89
90       SocketDomain
91
92       "SocketDomain" instructs the wheel to create a socket within a
93       particular domain.  Supported domains are "AF_UNIX", "AF_INET",
94       "AF_INET6", "PF_UNIX", "PF_INET", and "PF_INET6".  If omitted, the
95       socket will be created in the "AF_INET" domain.
96
97       POE::Wheel::SocketFactory contains a table of supported domains and the
98       instructions needed to create them.  Please send patches to support
99       additional domains, as needed.
100
101       Note: "AF_INET6" and "PF_INET6" are supplied by the Socket module
102       included in Perl 5.8.0 or later.  Perl versions before 5.8.0 should not
103       attempt to use IPv6 until someone contributes a workaround.
104
105       IPv6 support requires a Socket module that implements getaddrinfo() and
106       unpack_sockaddr_in6().  There may be other modules that perform these
107       functions, but most if not all of them have been deprecated with the
108       advent of proper core Socket support for IPv6.
109
110       SocketType
111
112       "SocketType" supplies the socket() call with a particular socket type,
113       which may be "SOCK_STREAM" or "SOCK_DGRAM".  "SOCK_STREAM" is the
114       default if "SocketType" is not supplied.
115
116       SocketProtocol
117
118       "SocketProtocol" sets the socket() call's protocol.  Protocols may be
119       specified by number or name.  "SocketProtocol" is ignored for UNIX
120       domain sockets.
121
122       The protocol defaults to "tcp" for INET domain sockets.  There is no
123       default for other socket domains.
124
125       Setting Socket Options
126
127       POE::Wheel::SocketFactory uses ioctl(), fcntl() and setsockopt() to set
128       socket options after the socket is created.  All sockets are set non-
129       blocking, and bound sockets may be made reusable.
130
131       Reuse
132
133       When set, the "Reuse" parameter allows a bound port to be reused
134       immediately.  "Reuse" is considered enabled if it contains "yes", "on",
135       or a true numeric value.  All other values disable port reuse, as does
136       omitting "Reuse" entirely.
137
138       For security purposes, a port cannot be reused for a minute or more
139       after a server has released it.  This gives clients time to realize the
140       port has been abandoned.  Otherwise a malicious service may snatch up
141       the port and spoof the legitimate service.
142
143       It's also terribly annoying to wait a minute or more between server
144       invocations, especially during development.
145
146       Bind the Socket to an Address and Port
147
148       A socket may optionally be bound to a specific interface and port.  The
149       "INADDR_ANY" address may be used to bind to a specific port across all
150       interfaces.
151
152       Sockets are bound using bind().  POE::Wheel::SocketFactory parameters
153       beginning with "Bind" control how bind() is called.
154
155       BindAddress
156
157       "BindAddress" sets an address to bind the socket's local endpoint to.
158       "INADDR_ANY" will be used if "BindAddress" is not specified.
159
160       "BindAddress" may contain either a string or a packed Internet address
161       (for "INET" domain sockets).  The string parameter should be a dotted
162       numeric address or a resolvable host name.  Note that the host name
163       will be resolved with a blocking call.  If this is not desired, use
164       POE::Component::Client::DNS to perform a non-blocking name resolution.
165
166       When used to bind a "UNIX" domain socket, "BindAddress" should contain
167       a path describing the socket's filename.  This is required for server
168       sockets and datagram client sockets.  "BindAddress" has no default
169       value for UNIX sockets.
170
171       BindPort
172
173       "BindPort" is only meaningful for "INET" domain sockets.  It contains a
174       port on the "BindAddress" interface where the socket will be bound.  It
175       defaults to 0 if omitted, which will cause the bind() call to choose an
176       indeterminate unallocated port.
177
178       "BindPort" may be a port number or a name that can be looked up in the
179       system's services (or equivalent) database.
180
181       Connectionless Sockets
182
183       Connectionless sockets may interact with remote endpoints without
184       needing to listen() for connections or connect() to remote addresses.
185
186       This class of sockets is complete after the bind() call.
187
188       Connecting the Socket to a Remote Endpoint
189
190       A socket may either listen for connections to arrive, initiate
191       connections to a remote endpoint, or be connectionless (such as in the
192       case of UDP sockets).
193
194       POE::Wheel::SocketFactory will initiate a client connection when new()
195       is capped with parameters that describe a remote endpoint.  In all
196       other cases, the socket will either listen for connections or be
197       connectionless depending on the socket type.
198
199       The following parameters describe a socket's remote endpoint.  They
200       determine how POE::Wheel::SocketFactory will call Perl's built-in
201       connect() function.
202
203       RemoteAddress
204
205       "RemoteAddress" specifies the remote address to which a socket should
206       connect.  If present, POE::Wheel::SocketFactory will create a client
207       socket that attempts to collect to the "RemoteAddress".  Otherwise, if
208       the protocol warrants it, the wheel will create a listening socket and
209       attempt to accept connections.
210
211       As with the bind address, "RemoteAddress" may be a string containing a
212       dotted quad or a resolvable host name.  It may also be a packed
213       Internet address, or a UNIX socket path.  It will be packed, with or
214       without an accompanying "RemotePort", as necessary for the socket
215       domain.
216
217       RemotePort
218
219       "RemotePort" is the port to which the socket should connect.  It is
220       required for "INET" client sockets, since the remote endpoint must
221       contain both an address and a port.
222
223       The remote port may be numeric, or it may be a symbolic name found in
224       /etc/services or the equivalent for your operating system.
225
226       Listening for Connections
227
228       Streaming sockets that have no remote endpoint are considered to be
229       server sockets.  POE::Wheel::SocketFactory will listen() for
230       connections to these sockets, accept() the new clients, and send the
231       application events with the new client sockets.
232
233       POE::Wheel::SocketFactory constructor parameters beginning with
234       "Listen" control how the listen() function is called.
235
236       ListenQueue
237
238       "ListenQueue" specifies the length of the socket's listen() queue.  It
239       defaults to "SOMAXCONN" if omitted.  "ListenQueue" values greater than
240       "SOMAXCONN" will be clipped to "SOMAXCONN".  Excessively large
241       "ListenQueue" values are not necessarily portable, and may cause errors
242       in some rare cases.
243
244       Emitting Events
245
246       POE::Wheel::SocketFactory emits a small number of events depending on
247       what happens during socket setup or while listening for new
248       connections.
249
250       See "PUBLIC EVENTS" for more details.
251
252       SuccessEvent
253
254       "SuccessEvent" names the event that will be emitted whenever
255       POE::Wheel::SocketFactory succeeds in creating a new socket.
256
257       For connectionless sockets, "SuccessEvent" happens just after the
258       socket is created.
259
260       For client connections, "SuccessEvent" is fired when the connection has
261       successfully been established with the remote endpoint.
262
263       Server sockets emit a "SuccessEvent" for every successfully accepted
264       client.
265
266       FailureEvent
267
268       "FailureEvent" names the event POE::Wheel::SocketFactory will emit
269       whenever something goes wrong.  It usually represents some kind of
270       built-in function call error.  See "PUBLIC EVENTS" for details, as some
271       errors are handled internally by this wheel.
272
273   event
274       event() allows a session to change the events emitted by a wheel
275       without destroying and re-creating the wheel.  It accepts one or more
276       of the events listed in "PUBLIC EVENTS".  Undefined event names disable
277       those events.
278
279       event() is described in more depth in POE::Wheel.
280
281   getsockname
282       getsockname() behaves like the built-in function of the same name.  It
283       returns the local endpoint information for POE::Wheel::SocketFactory's
284       encapsulated listening socket.
285
286       getsockname() allows applications to determine the address and port to
287       which POE::Wheel::SocketFactory has bound its listening socket.
288
289       Test applications may use getsockname() to find the server socket after
290       POE::Wheel::SocketFactory has bound to INADDR_ANY port 0.
291
292       Since there is no event fired immediately after a successful creation
293       of a listening socket, applications can use getsockname() to verify
294       this.
295
296        use Socket 'unpack_sockaddr_in';
297
298        my $listener = POE::Wheel::SocketFactory->new(
299            BindPort     => 123,
300            SuccessEvent => 'got_client',
301            FailureEvent => 'listener_failed',
302            Reuse        => 'on',
303        );
304
305        my ($port, $addr) = unpack_sockaddr_in($listener->getsockname);
306        print "Socket successfully bound\n" if $port;
307
308   ID
309       ID() returns the wheel's unique ID.  The ID will also be included in
310       every event the wheel generates.  Applications can match events back to
311       the objects that generated them.
312
313   pause_accept
314       Applications may occasionally need to block incoming connections.
315       pause_accept() pauses the event watcher that triggers accept().  New
316       inbound connections will stack up in the socket's listen() queue until
317       the queue overflows or the application calls resume_accept().
318
319       Pausing accept() can limit the amount of load a server generates.  It's
320       also useful in pre-forking servers when the master process shouldn't
321       accept connections at all.
322
323       pause_accept() and resume_accept() is quicker and more reliable than
324       dynamically destroying and re-creating a POE::Wheel::SocketFactory
325       object.
326
327   resume_accept
328       resume_accept() resumes the watcher that triggers accept().  See
329       "pause_accept" for a more detailed discussion.
330

PUBLIC EVENTS

332       POE::Wheel::SocketFactory emits two public events.
333
334   SuccessEvent
335       "SuccessEvent" names an event that will be sent to the creating session
336       whenever a POE::Wheel::SocketFactory has created a new socket.  For
337       connectionless sockets, it's when the socket is created.  For
338       connecting clients, it's after the connection has been established.
339       And for listening servers, "SuccessEvent" is fired after each new
340       client is accepted.
341
342       Common SuccessEvent Parameters
343
344       In all cases, $_[ARG0] holds the new socket's filehandle, and $_[ARG3]
345       contains the POE::Wheel::SocketFactory's ID.  Other parameters vary
346       depending on the socket's domain and whether it's listening or
347       connecting.  See below for the differences.
348
349       INET SuccessEvent Parameters
350
351       For INET sockets, $_[ARG1] and $_[ARG2] hold the socket's remote
352       address and port, respectively.  The address is packed; see "inet_ntop"
353       in Socket if a human-readable address is needed.
354
355         sub handle_new_client {
356           my $accepted_socket = $_[ARG0];
357
358           my $peer_host = inet_ntop(
359             ((length($_[ARG1]) == 4) ? AF_INET : AF_INET6),
360             $_[ARG1]
361           );
362
363           print(
364             "Wheel $_[ARG3] accepted a connection from ",
365             "$peer_host port $peer_port\n"
366           );
367
368           spawn_connection_session($accepted_handle);
369         }
370
371       UNIX Client SuccessEvent Parameters
372
373       For UNIX client sockets, $_[ARG1] often (but not always) holds the
374       server address.  Some systems cannot retrieve a UNIX socket's remote
375       address.  $_[ARG2] is always undef for UNIX client sockets.
376
377       UNIX Server SuccessEvent Parameters
378
379       According to Perl Cookbook, the remote address returned by accept() on
380       UNIX sockets is undefined, so $_[ARG1] and $_[ARG2] are also undefined
381       in this case.
382
383   FailureEvent
384       "FailureEvent" names the event that will be emitted when a socket error
385       occurs.  POE::Wheel::SocketFactory handles "EAGAIN" internally, so it
386       doesn't count as an error.
387
388       "FailureEvent" events include the standard error event parameters:
389
390       $_[ARG0] describes which part of socket creation failed.  It often
391       holds a Perl built-in function name.
392
393       $_[ARG1] and $_[ARG2] describe how the operation failed.  They contain
394       the numeric and stringified versions of $!, respectively.  An
395       application cannot merely check the global $! variable since it may
396       change during event dispatch.
397
398       Finally, $_[ARG3] contains the ID for the POE::Wheel::SocketFactory
399       instance that generated the event.  See "ID" and "ID" in POE::Wheel for
400       uses for wheel IDs.
401
402       A sample FailureEvent handler:
403
404         sub handle_failure {
405           my ($operation, $errnum, $errstr, $wheel_id) = @_[ARG0..ARG3];
406           warn "Wheel $wheel_id generated $operation error $errnum: $errstr\n";
407           delete $_[HEAP]{wheels}{$wheel_id}; # shut down that wheel
408         }
409

SEE ALSO

411       POE::Wheel describes the basic operations of all wheels in more depth.
412       You need to know this.
413
414       Socket::GetAddrInfo is required for IPv6 work.
415       POE::Wheel::SocketFactory will load it automatically if it's installed.
416       SocketDomain => AF_INET6 is required to trigger IPv6 behaviors.
417       AF_INET6 is exported by the Socket module on all but the oldest
418       versions of Perl 5.  If your Socket doesn't provide AF_INET6, try
419       installing Socket6 instead.
420
421       The SEE ALSO section in POE contains a table of contents covering the
422       entire POE distribution.
423

BUGS

425       Many (if not all) of the croak/carp/warn/die statements should fire
426       back "FailureEvent" instead.
427
428       SocketFactory is only tested with UNIX streams and INET sockets using
429       the UDP and TCP protocols.  Others should work after the module's
430       internal configuration tables are updated.  Please send patches.
431

AUTHORS & COPYRIGHTS

433       Please see POE for more information about authors and contributors.
434
435
436
437perl v5.36.0                      2023-01-20      POE::Wheel::SocketFactory(3)
Impressum