1POE::Wheel::SocketFactoUrsye(r3)Contributed Perl DocumenPtOaEt:i:oWnheel::SocketFactory(3)
2
3
4
6 POE::Wheel::SocketFactory - non-blocking socket creation
7
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
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
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 Socket6 module,
102 which is available on the CPAN. You must have Socket6 loaded before
103 SocketFactory can create IPv6 sockets.
104
105 TODO - Example.
106
107 SocketType
108
109 "SocketType" supplies the socket() call with a particular socket type,
110 which may be "SOCK_STREAM" or "SOCK_DGRAM". "SOCK_STREAM" is the
111 default if "SocketType" is not supplied.
112
113 TODO - Example.
114
115 SocketProtocol
116
117 "SocketProtocol" sets the socket() call's protocol. Protocols may be
118 specified by number or name. "SocketProtocol" is ignored for UNIX
119 domain sockets.
120
121 The protocol defaults to "tcp" for INET domain sockets. There is no
122 default for other socket domains.
123
124 TODO - Example.
125
126 Setting Socket Options
127
128 POE::Wheel::SocketFactory uses ioctl(), fcntl() and setsockopt() to set
129 socket options after the socket is created. All sockets are set non-
130 blocking, and bound sockets may be made reusable.
131
132 Reuse
133
134 When set, the "Reuse" parameter allows a bound port to be reused
135 immediately. "Reuse" is considered enabled if it contains "yes", "on",
136 or a true numeric value. All other values disable port reuse, as does
137 omitting "Reuse" entirely.
138
139 For security purposes, a port cannot be reused for a minute or more
140 after a server has released it. This gives clients time to realize the
141 port has been abandoned. Otherwise a malicious service may snatch up
142 the port and spoof the legitimate service.
143
144 It's also terribly annoying to wait a minute or more between server
145 invocations, especially during development.
146
147 Bind the Socket to an Address and Port
148
149 A socket may optionally be bound to a specific interface and port. The
150 "INADDR_ANY" address may be used to bind to a specific port across all
151 interfaces.
152
153 Sockets are bound using bind(). POE::Wheel::SocketFactory parameters
154 beginning with "Bind" control how bind() is called.
155
156 BindAddress
157
158 "BindAddress" sets an address to bind the socket's local endpoint to.
159 "INADDR_ANY" will be used if "BindAddress" is not specified.
160
161 "BindAddress" may contain either a string or a packed Internet address
162 (for "INET" domain sockets). The string parameter should be a dotted
163 numeric address or a resolvable host name. Note that the host name
164 will be resolved with a blocking call. If this is not desired, use
165 POE::Component::Client::DNS to perform a non-blocking name resolution.
166
167 When used to bind a "UNIX" domain socket, "BindAddress" should contain
168 a path describing the socket's filename. This is required for server
169 sockets and datagram client sockets. "BindAddress" has no default
170 value for UNIX sockets.
171
172 TODO - Example.
173
174 BindPort
175
176 "BindPort" is only meaningful for "INET" domain sockets. It contains a
177 port on the "BindAddress" interface where the socket will be bound. It
178 defaults to 0 if omitted, which will cause the bind() call to choose an
179 indeterminate unallocated port.
180
181 "BindPort" may be a port number or a name that can be looked up in the
182 system's services (or equivalent) database.
183
184 TODO - Example.
185
186 Connectionless Sockets
187
188 Connectionless sockets may interact with remote endpoints without
189 needing to listen() for connections or connect() to remote addresses.
190
191 This class of sockets is complete after the bind() call.
192
193 TODO - Example.
194
195 Connecting the Socket to a Remote Endpoint
196
197 A socket may either listen for connections to arrive, initiate
198 connections to a remote endpoint, or be connectionless (such as in the
199 case of UDP sockets).
200
201 POE::Wheel::SocketFactory will initiate a client connection when new()
202 is capped with parameters that describe a remote endpoint. In all
203 other cases, the socket will either listen for connections or be
204 connectionless depending on the socket type.
205
206 The following parameters describe a socket's remote endpoint. They
207 determine how POE::Wheel::SocketFactory will call Perl's built-in
208 connect() function.
209
210 RemoteAddress
211
212 "RemoteAddress" specifies the remote address to which a socket should
213 connect. If present, POE::Wheel::SocketFactory will create a client
214 socket that attempts to collect to the "RemoteAddress". Otherwise, if
215 the protocol warrants it, the wheel will create a listening socket and
216 attempt to accept connections.
217
218 As with the bind address, "RemoteAddress" may be a string containing a
219 dotted quad or a resolvable host name. It may also be a packed
220 Internet address, or a UNIX socket path. It will be packed, with or
221 without an accompanying "RemotePort", as necessary for the socket
222 domain.
223
224 TODO - Example.
225
226 RemotePort
227
228 "RemotePort" is the port to which the socket should connect. It is
229 required for "INET" client sockets, since the remote endpoint must
230 contain both an address and a port.
231
232 The remote port may be numeric, or it may be a symbolic name found in
233 /etc/services or the equivalent for your operating system.
234
235 TODO - Example.
236
237 Listening for Connections
238
239 Streaming sockets that have no remote endpoint are considered to be
240 server sockets. POE::Wheel::SocketFactory will listen() for
241 connections to these sockets, accept() the new clients, and send the
242 application events with the new client sockets.
243
244 POE::Wheel::SocketFactory constructor parameters beginning with
245 "Listen" control how the listen() function is called.
246
247 ListenQueue
248
249 "ListenQueue" specifies the length of the socket's listen() queue. It
250 defaults to "SOMAXCONN" if omitted. "ListenQueue" values greater than
251 "SOMAXCONN" will be clipped to "SOMAXCONN". Excessively large
252 "ListenQueue" values are not necessarily portable, and may cause errors
253 in some rare cases.
254
255 TODO - Example.
256
257 Emitting Events
258
259 POE::Wheel::SocketFactory emits a small number of events depending on
260 what happens during socket setup or while listening for new
261 connections.
262
263 See "PUBLIC EVENTS" for more details.
264
265 SuccessEvent
266
267 "SuccessEvent" names the event that will be emitted whenever
268 POE::Wheel::SocketFactory succeeds in creating a new socket.
269
270 For connectionless sockets, "SuccessEvent" happens just after the
271 socket is created.
272
273 For client connections, "SuccessEvent" is fired when the connection has
274 successfully been established with the remote endpoint.
275
276 Server sockets emit a "SuccessEvent" for every successfully accepted
277 client.
278
279 FailureEvent
280
281 "FailureEvent" names the event POE::Wheel::SocketFactory will emit
282 whenever something goes wrong. It usually represents some kind of
283 built-in function call error. See "PUBLIC EVENTS" for details, as some
284 errors are handled internally by this wheel.
285
286 event
287 event() allows a session to change the events emitted by a wheel
288 without destroying and re-creating the wheel. It accepts one or more
289 of the events listed in "PUBLIC EVENTS". Undefined event names disable
290 those events.
291
292 event() is described in more depth in POE::Wheel.
293
294 TODO - Example.
295
296 getsockname
297 getsockname() behaves like the built-in function of the same name. It
298 returns the local endpoint information for POE::Wheel::SocketFactory's
299 encapsulated listening socket.
300
301 getsockname() allows applications to determine the address and port to
302 which POE::Wheel::SocketFactory has bound its listening socket.
303
304 Test applications may use getsockname() to find the server socket after
305 POE::Wheel::SocketFactory has bound to INADDR_ANY port 0.
306
307 TODO - Example.
308
309 ID
310 ID() returns the wheel's unique ID. The ID will also be included in
311 every event the wheel generates. Applications can match events back to
312 the objects that generated them.
313
314 TODO - Example.
315
316 pause_accept
317 Applications may occasionally need to block incoming connections.
318 pause_accept() pauses the event watcher that triggers accept(). New
319 inbound connections will stack up in the socket's listen() queue until
320 the queue overflows or the application calls resume_accept().
321
322 Pausing accept() can limit the amount of load a server generates. It's
323 also useful in pre-forking servers when the master process shouldn't
324 accept connections at all.
325
326 pause_accept() and resume_accept() is quicker and more reliable than
327 dynamically destroying and re-creating a POE::Wheel::SocketFactory
328 object.
329
330 TODO - Example.
331
332 resume_accept
333 resume_accept() resumes the watcher that triggers accept(). See
334 "pause_accept" for a more detailed discussion.
335
337 POE::Wheel::SocketFactory emits two public events.
338
339 SuccessEvent
340 "SuccessEvent" names an event that will be sent to the creating session
341 whenever a POE::Wheel::SocketFactory has created a new socket. For
342 connectionless sockets, it's when the socket is created. For
343 connecting clients, it's after the connection has been established.
344 And for listening servers, "SuccessEvent" is fired after each new
345 client is accepted.
346
347 Common SuccessEvent Parameters
348
349 In all cases, $_[ARG0] holds the new socket's filehandle, and $_[ARG3]
350 contains the POE::Wheel::SocketFactory's ID. Other parameters vary
351 depending on the socket's domain and whether it's listening or
352 connecting. See below for the differences.
353
354 INET SuccessEvent Parameters
355
356 For INET sockets, $_[ARG1] and $_[ARG2] hold the socket's remote
357 address and port, respectively. The address is packed; see
358 "inet_nota()" in Socket if a human-readable version is needed.
359
360 sub handle_new_client {
361 my $accepted_socket = $_[ARG0];
362
363 my $peer_host = inet_ntoa($_[ARG1]);
364 print(
365 "Wheel $_[ARG3] accepted a connection from ",
366 "$peer_host port $peer_port\n"
367 );
368
369 spawn_connection_session($accepted_handle);
370 }
371
372 UNIX Client SuccessEvent Parameters
373
374 For UNIX client sockets, $_[ARG1] often (but not always) holds the
375 server address. Some systems cannot retrieve a UNIX socket's remote
376 address. $_[ARG2] is always undef for UNIX client sockets.
377
378 UNIX Server SuccessEvent Parameters
379
380 According to Perl Cookbook, the remote address returned by accept() on
381 UNIX sockets is undefined, so $_[ARG1] and $_[ARG2] are also undefined
382 in this case.
383
384 FailureEvent
385 "FailureEvent" names the event that will be emitted when a socket error
386 occurs. POE::Wheel::SocketFactory handles "EAGAIN" internally, so it
387 doesn't count as an error.
388
389 "FailureEvent" events include the standard error event parameters:
390
391 $_[ARG0] describes which part of socket creation failed. It often
392 holds a Perl built-in function name.
393
394 $_[ARG1] and $_[ARG2] describe how the operation failed. They contain
395 the numeric and stringified versions of $!, respectively. An
396 application cannot merely check $! because
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
411 POE::Wheel describes the basic operations of all wheels in more depth.
412 You need to know this.
413
414 Socket6 is required for IPv6 work. POE::Wheel::SocketFactory will load
415 it automatically if it's installed, but applications will need to use
416 it themselves to get access to AF_INET6.
417
418 The SEE ALSO section in POE contains a table of contents covering the
419 entire POE distribution.
420
422 Many (if not all) of the croak/carp/warn/die statements should fire
423 back "FailureEvent" instead.
424
425 SocketFactory is only tested with UNIX streams and INET sockets using
426 the UDP and TCP protocols. Others should work after the module's
427 internal configuration tables are updated. Please send patches.
428
430 Please see POE for more information about authors and contributors.
431
432
433
434perl v5.12.1 2010-04-03 POE::Wheel::SocketFactory(3)