{
    "mode": "perldoc",
    "parameter": "IO::Multiplex",
    "section": "",
    "url": "https://www.chedong.com/phpMan.php/perldoc/IO%3A%3AMultiplex/json",
    "generated": "2026-06-09T21:13:39Z",
    "synopsis": "use IO::Multiplex;\nmy $mux = new IO::Multiplex;\n$mux->add($fh1);\n$mux->add(\\*FH2);\n$mux->setcallbackobject(...);\n$mux->listen($serversocket);\n$mux->loop;\nsub muxinput { ... }\n\"IO::Multiplex\" is designed to take the effort out of managing multiple file handles. It is\nessentially a really fancy front end to the \"select\" system call. In addition to maintaining the\n\"select\" loop, it buffers all input and output to/from the file handles. It can also accept\nincoming connections on one or more listen sockets.",
    "sections": {
        "NAME": {
            "content": "IO::Multiplex - Manage IO on many file handles\n",
            "subsections": []
        },
        "SYNOPSIS": {
            "content": "use IO::Multiplex;\n\nmy $mux = new IO::Multiplex;\n$mux->add($fh1);\n$mux->add(\\*FH2);\n$mux->setcallbackobject(...);\n$mux->listen($serversocket);\n$mux->loop;\n\nsub muxinput { ... }\n\n\"IO::Multiplex\" is designed to take the effort out of managing multiple file handles. It is\nessentially a really fancy front end to the \"select\" system call. In addition to maintaining the\n\"select\" loop, it buffers all input and output to/from the file handles. It can also accept\nincoming connections on one or more listen sockets.\n",
            "subsections": []
        },
        "DESCRIPTION": {
            "content": "It is object oriented in design, and will notify you of significant events by calling methods on\nan object that you supply. If you are not using objects, you can simply supply \"PACKAGE\"\ninstead of an object reference.\n\nYou may have one callback object registered for each file handle, or one global one. Possibly\nboth -- the per-file handle callback object will be used instead of the global one.\n\nEach file handle may also have a timer associated with it. A callback function is called when\nthe timer expires.\n",
            "subsections": [
                {
                    "name": "Handling input on descriptors",
                    "content": "When input arrives on a file handle, the \"muxinput\" method is called on the appropriate\ncallback object. This method is passed three arguments (in addition to the object reference\nitself of course):\n\n1   a reference to the mux,\n\n2   A reference to the file handle, and\n\n3   a reference to the input buffer for the file handle.\n\nThe method should remove the data that it has consumed from the reference supplied. It may leave\nunconsumed data in the input buffer.\n"
                },
                {
                    "name": "Handling output to descriptors",
                    "content": "If \"IO::Multiplex\" did not handle output to the file handles as well as input from them, then\nthere is a chance that the program could block while attempting to write. If you let the\nmultiplexer buffer the output, it will write the data only when the file handle is capable of\nreceiveing it.\n\nThe basic method for handing output to the multiplexer is the \"write\" method, which simply takes\na file descriptor and the data to be written, like this:\n\n$mux->write($fh, \"Some data\");\n\nFor convenience, when the file handle is \"add\"ed to the multiplexer, it is tied to a special\nclass which intercepts all attempts to write to the file handle. Thus, you can use print and\nprintf to send output to the handle in a normal manner:\n\nprintf $fh \"%s%d%X\", $foo, $bar, $baz\n\nUnfortunately, Perl support for tied file handles is incomplete, and functions such as \"send\"\ncannot be supported.\n\nAlso, file handle object methods such as the \"send\" method of \"IO::Socket\" cannot be\nintercepted.\n"
                }
            ]
        },
        "EXAMPLES": {
            "content": "",
            "subsections": [
                {
                    "name": "Simple Example",
                    "content": "This is a simple telnet-like program, which demonstrates the concepts covered so far. It does\nnot really work too well against a telnet server, but it does OK against the sample server\npresented further down.\n\nuse IO::Socket;\nuse IO::Multiplex;\n\n# Create a multiplex object\nmy $mux  = new IO::Multiplex;\n# Connect to the host/port specified on the command line,\n# or localhost:23\nmy $sock = new IO::Socket::INET(Proto    => 'tcp',\nPeerAddr => shift || 'localhost',\nPeerPort => shift || 23)\nor die \"socket: $@\";\n\n# add the relevant file handles to the mux\n$mux->add($sock);\n$mux->add(\\*STDIN);\n# We want to buffer output to the terminal.  This prevents the program\n# from blocking if the user hits CTRL-S for example.\n$mux->add(\\*STDOUT);\n\n# We're not object oriented, so just request callbacks to the\n# current package\n$mux->setcallbackobject(PACKAGE);\n\n# Enter the main mux loop.\n$mux->loop;\n\n# muxinput is called when input is available on one of\n# the descriptors.\nsub muxinput {\nmy $package = shift;\nmy $mux     = shift;\nmy $fh      = shift;\nmy $input   = shift;\n\n# Figure out whence the input came, and send it on to the\n# other place.\nif ($fh == $sock) {\nprint STDOUT $$input;\n} else {\nprint $sock $$input;\n}\n# Remove the input from the input buffer.\n$$input = '';\n}\n\n# This gets called if the other end closes the connection.\nsub muxclose {\nprint STDERR \"Connection Closed\\n\";\nexit;\n}\n\nA server example\nServers are just as simple to write. We just register a listen socket with the multiplex object\n\"listen\" method. It will automatically accept connections on it and add them to its list of\nactive file handles.\n\nThis example is a simple chat server.\n\nuse IO::Socket;\nuse IO::Multiplex;\n\nmy $mux  = new IO::Multiplex;\n\n# Create a listening socket\nmy $sock = new IO::Socket::INET(Proto     => 'tcp',\nLocalPort => shift || 2300,\nListen    => 4)\nor die \"socket: $@\";\n\n# We use the listen method instead of the add method.\n$mux->listen($sock);\n\n$mux->setcallbackobject(PACKAGE);\n$mux->loop;\n\nsub muxinput {\nmy $package = shift;\nmy $mux     = shift;\nmy $fh      = shift;\nmy $input   = shift;\n\n# The handles method returns a list of references to handles which\n# we have registered, except for listen sockets.\nforeach $c ($mux->handles) {\nprint $c $$input;\n}\n$$input = '';\n}\n\nA more complex server example\nLet us take a look at the beginnings of a multi-user game server. We will have a Player object\nfor each player.\n\n# Paste the above example in here, up to but not including the\n# muxinput subroutine.\n\n# muxconnection is called when a new connection is accepted.\nsub muxconnection {\nmy $package = shift;\nmy $mux     = shift;\nmy $fh      = shift;\n\n# Construct a new player object\nPlayer->new($mux, $fh);\n}\n\npackage Player;\n\nmy %players = ();\n\nsub new {\nmy $package = shift;\nmy $self    = bless { mux  => shift,\nfh   => shift } => $package;\n\n# Register the new player object as the callback specifically for\n# this file handle.\n\n$self->{mux}->setcallbackobject($self, $self->{fh});\nprint $self->{fh}\n\"Greetings, Professor.  Would you like to play a game?\\n\";\n\n# Register this player object in the main list of players\n$players{$self} = $self;\n$mux->settimeout($self->{fh}, 1);\n}\n\nsub players { return values %players; }\n\nsub muxinput {\nmy $self = shift;\nshift; shift;         # These two args are boring\nmy $input = shift;    # Scalar reference to the input\n\n# Process each line in the input, leaving partial lines\n# in the input buffer\nwhile ($$input =~ s/^(.*?)\\n//) {\n$self->processcommand($1);\n}\n}\n\nsub muxclose {\nmy $self = shift;\n\n# Player disconnected;\n# [Notify other players or something...]\ndelete $players{$self};\n}\n# This gets called every second to update player info, etc...\nsub muxtimeout {\nmy $self = shift;\nmy $mux  = shift;\n\n$self->heartbeat;\n$mux->settimeout($self->{fh}, 1);\n}\n"
                }
            ]
        },
        "METHODS": {
            "content": "new\nConstruct a new \"IO::Multiplex\" object.\n\n$mux = new IO::Multiplex;\n\nlisten\nAdd a socket to be listened on. The socket should have had the \"bind\" and \"listen\" system calls\nalready applied to it. The \"IO::Socket\" module will do this for you.\n\n$socket = new IO::Socket::INET(Listen => ..., LocalAddr => ...);\n$mux->listen($socket);\n\nConnections will be automatically accepted and \"add\"ed to the multiplex object. \"The\nmuxconnection\" callback method will also be called.\n\nadd\nAdd a file handle to the multiplexer.\n\n$mux->add($fh);\n\nAs a side effect, this sets non-blocking mode on the handle, and disables STDIO buffering. It\nalso ties it to intercept output to the handle.\n\nremove\nRemoves a file handle from the multiplexer. This also unties the handle. It does not currently\nturn STDIO buffering back on, or turn off non-blocking mode.\n\n$mux->remove($fh);\n\nsetcallbackobject\nSet the object on which callbacks are made. If you are not using objects, you can specify the\nname of the package into which the method calls are to be made.\n\nIf a file handle is supplied, the callback object is specific for that handle:\n\n$mux->setcallbackobject($object, $fh);\n\nOtherwise, it is considered a default callback object, and is used when events occur on a file\nhandle that does not have its own callback object.\n\n$mux->setcallbackobject(PACKAGE);\n\nThe previously registered object (if any) is returned.\n\nSee also the CALLBACK INTERFACE section.\n\nkilloutput\nRemove any pending output on a file descriptor.\n\n$mux->killoutput($fh);\n\noutbuffer\nReturn or set the output buffer for a descriptor\n\n$output = $mux->outbuffer($fh);\n$mux->outbuffer($fh, $output);\n\ninbuffer\nReturn or set the input buffer for a descriptor\n\n$input = $mux->inbuffer($fh);\n$mux->inbuffer($fh, $input);\n\nsettimeout\nSet the timer for a file handle. The timeout value is a certain number of seconds in the future,\nafter which the \"muxtimeout\" callback is called.\n\nIf the \"Time::HiRes\" module is installed, the timers may be specified in fractions of a second.\n\nTimers are not reset automatically.\n\n$mux->settimeout($fh, 23.6);\n\nUse \"$mux->settimeout($fh, undef)\" to cancel a timer.\n\nhandles\nReturns a list of handles that the \"IO::Multiplex\" object knows about, excluding listen sockets.\n\n@handles = $mux->handles;\n\nloop\nEnter the main loop and start processing IO events.\n\n$mux->loop;\n\nendloop\nPrematurly terminate the loop. The loop will automatically terminate when there are no remaining\ndescriptors to be watched.\n\n$mux->endloop;\n\nudppeer\nGet peer endpoint of where the last udp packet originated.\n\n$saddr = $mux->udppeer($fh);\n\nisudp\nSometimes UDP packets require special attention. This method will tell if a file handle is of\ntype UDP.\n\n$isudp = $mux->isudp($fh);\n\nwrite\nSend output to a file handle.\n\n$mux->write($fh, \"'ere I am, JH!\\n\");\n\nshutdown\nShut down a socket for reading or writing or both. See the \"shutdown\" Perl documentation for\nfurther details.\n\nIf the shutdown is for reading, it happens immediately. However, shutdowns for writing are\ndelayed until any pending output has been successfully written to the socket.\n\n$mux->shutdown($socket, 1);\n\nclose\nClose a handle. Always use this method to close a handle that is being watched by the\nmultiplexer.\n\n$mux->close($fh);\n",
            "subsections": []
        },
        "CALLBACK INTERFACE": {
            "content": "Callback objects should support the following interface. You do not have to provide all of these\nmethods, just provide the ones you are interested in.\n\nAll methods receive a reference to the callback object (or package) as their first argument, in\nthe traditional object oriented way. References to the \"IO::Multiplex\" object and the relevant\nfile handle are also provided. This will be assumed in the method descriptions.\n\nmuxinput\nCalled when input is ready on a descriptor. It is passed a reference to the input buffer. It\nshould remove any input that it has consumed, and leave any partially received data in the\nbuffer.\n\nsub muxinput {\nmy $self = shift;\nmy $mux  = shift;\nmy $fh   = shift;\nmy $data = shift;\n\n# Process each line in the input, leaving partial lines\n# in the input buffer\nwhile ($$data =~ s/^(.*?\\n)//) {\n$self->processcommand($1);\n}\n}\n\nmuxeof\nThis is called when an end-of-file condition is present on the descriptor. This is does not\nnessecarily mean that the descriptor has been closed, as the other end of a socket could have\nused \"shutdown\" to close just half of the socket, leaving us free to write data back down the\nstill open half. Like muxinput, it is also passed a reference to the input buffer. It should\nconsume the entire buffer or else it will just be lost.\n\nIn this example, we send a final reply to the other end of the socket, and then shut it down for\nwriting. Since it is also shut down for reading (implicly by the EOF condition), it will be\nclosed once the output has been sent, after which the muxclose callback will be called.\n\nsub muxeof {\nmy $self = shift;\nmy $mux  = shift;\nmy $fh   = shift;\n\nprint $fh \"Well, goodbye then!\\n\";\n$mux->shutdown($fh, 1);\n}\n\nmuxclose\nCalled when a handle has been completely closed. At the time that \"muxclose\" is called, the\nhandle will have been removed from the multiplexer, and untied.\n\nmuxoutbufferempty\nCalled after all pending output has been written to the file descriptor.\n\nmuxconnection\nCalled upon a new connection being accepted on a listen socket.\n\nmuxtimeout\nCalled when a timer expires.\n",
            "subsections": []
        },
        "AUTHOR": {
            "content": "Copyright 1999 Bruce J Keeler <bruce@gridpoint.com>\n\nCopyright 2001-2008 Rob Brown <bbb@cpan.org>\n\nReleased under the same terms as Perl itself.\n\n$Id: Multiplex.pm,v 1.45 2015/04/09 21:27:54 rob Exp $\n",
            "subsections": []
        }
    },
    "summary": "IO::Multiplex - Manage IO on many file handles",
    "flags": [],
    "examples": [
        "This is a simple telnet-like program, which demonstrates the concepts covered so far. It does",
        "not really work too well against a telnet server, but it does OK against the sample server",
        "presented further down.",
        "use IO::Socket;",
        "use IO::Multiplex;",
        "# Create a multiplex object",
        "my $mux  = new IO::Multiplex;",
        "# Connect to the host/port specified on the command line,",
        "# or localhost:23",
        "my $sock = new IO::Socket::INET(Proto    => 'tcp',",
        "PeerAddr => shift || 'localhost',",
        "PeerPort => shift || 23)",
        "or die \"socket: $@\";",
        "# add the relevant file handles to the mux",
        "$mux->add($sock);",
        "$mux->add(\\*STDIN);",
        "# We want to buffer output to the terminal.  This prevents the program",
        "# from blocking if the user hits CTRL-S for example.",
        "$mux->add(\\*STDOUT);",
        "# We're not object oriented, so just request callbacks to the",
        "# current package",
        "$mux->setcallbackobject(PACKAGE);",
        "# Enter the main mux loop.",
        "$mux->loop;",
        "# muxinput is called when input is available on one of",
        "# the descriptors.",
        "sub muxinput {",
        "my $package = shift;",
        "my $mux     = shift;",
        "my $fh      = shift;",
        "my $input   = shift;",
        "# Figure out whence the input came, and send it on to the",
        "# other place.",
        "if ($fh == $sock) {",
        "print STDOUT $$input;",
        "} else {",
        "print $sock $$input;",
        "# Remove the input from the input buffer.",
        "$$input = '';",
        "# This gets called if the other end closes the connection.",
        "sub muxclose {",
        "print STDERR \"Connection Closed\\n\";",
        "exit;",
        "A server example",
        "Servers are just as simple to write. We just register a listen socket with the multiplex object",
        "\"listen\" method. It will automatically accept connections on it and add them to its list of",
        "active file handles.",
        "This example is a simple chat server.",
        "use IO::Socket;",
        "use IO::Multiplex;",
        "my $mux  = new IO::Multiplex;",
        "# Create a listening socket",
        "my $sock = new IO::Socket::INET(Proto     => 'tcp',",
        "LocalPort => shift || 2300,",
        "Listen    => 4)",
        "or die \"socket: $@\";",
        "# We use the listen method instead of the add method.",
        "$mux->listen($sock);",
        "$mux->setcallbackobject(PACKAGE);",
        "$mux->loop;",
        "sub muxinput {",
        "my $package = shift;",
        "my $mux     = shift;",
        "my $fh      = shift;",
        "my $input   = shift;",
        "# The handles method returns a list of references to handles which",
        "# we have registered, except for listen sockets.",
        "foreach $c ($mux->handles) {",
        "print $c $$input;",
        "$$input = '';",
        "A more complex server example",
        "Let us take a look at the beginnings of a multi-user game server. We will have a Player object",
        "for each player.",
        "# Paste the above example in here, up to but not including the",
        "# muxinput subroutine.",
        "# muxconnection is called when a new connection is accepted.",
        "sub muxconnection {",
        "my $package = shift;",
        "my $mux     = shift;",
        "my $fh      = shift;",
        "# Construct a new player object",
        "Player->new($mux, $fh);",
        "package Player;",
        "my %players = ();",
        "sub new {",
        "my $package = shift;",
        "my $self    = bless { mux  => shift,",
        "fh   => shift } => $package;",
        "# Register the new player object as the callback specifically for",
        "# this file handle.",
        "$self->{mux}->setcallbackobject($self, $self->{fh});",
        "print $self->{fh}",
        "\"Greetings, Professor.  Would you like to play a game?\\n\";",
        "# Register this player object in the main list of players",
        "$players{$self} = $self;",
        "$mux->settimeout($self->{fh}, 1);",
        "sub players { return values %players; }",
        "sub muxinput {",
        "my $self = shift;",
        "shift; shift;         # These two args are boring",
        "my $input = shift;    # Scalar reference to the input",
        "# Process each line in the input, leaving partial lines",
        "# in the input buffer",
        "while ($$input =~ s/^(.*?)\\n//) {",
        "$self->processcommand($1);",
        "sub muxclose {",
        "my $self = shift;",
        "# Player disconnected;",
        "# [Notify other players or something...]",
        "delete $players{$self};",
        "# This gets called every second to update player info, etc...",
        "sub muxtimeout {",
        "my $self = shift;",
        "my $mux  = shift;",
        "$self->heartbeat;",
        "$mux->settimeout($self->{fh}, 1);"
    ],
    "see_also": []
}