home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  

Perl CookbookPerl CookbookSearch this book

17.16. Writing a Multihomed Server

17.16.3. Discussion

Whereas getpeername (as discussed in Recipe 17.7) returns the address of the remote end of the socket, getsockname returns the address of the local end. When we've bound to INADDR_ANY, thus accepting connections on any address the machine has, we need to use getsockname to identify which address the client connected to.

If you're using IO::Socket::INET, your code will look like this:

$server = IO::Socket::INET->new(LocalPort => $server_port,
                                Type      => SOCK_STREAM,
                                Proto     => 'tcp',
                                Listen    => 10)
    or die "Can't create server socket: $@\n";

while ($client = $server->accept( )) {
    $my_socket_address = $client->sockname( );
    ($port, $myaddr)   = sockaddr_in($my_socket_address);
    # ...

If you don't specify a local port to IO::Socket::INET->new, your socket will be bound to INADDR_ANY.

If you want your server to listen only for a particular virtual host, don't use INADDR_ANY. Instead, bind to a specific host address:

use Socket;

$port = 4269;                       # port to bind to
$host = "specific.host.com";        # virtual host to listen on

socket(Server, PF_INET, SOCK_STREAM, getprotobyname("tcp"))
    or die "socket: $!";
bind(Server, sockaddr_in($port, inet_aton($host)))
    or die "bind: $!";
while ($client_address = accept(Client, Server)) {
    # ...

17.16.4. See Also

The getsockname function in Chapter 29 of Programming Perl and in perlfunc(1); the documentation for the standard Socket and IO::Socket modules; the section on "Sockets" in Chapter 16 of Programming Perl or perlipc(1)

Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.