Professional Web Applications Themes

IO::Socket::INET - Listen on exactly two IPs the same time? - PERL Miscellaneous

Hi there, I'm just writing some little perl-server using IO:Socket::INET. Now, I would like to make the server listen to more than one IP without listening to ALL IPs (0.0.0.0). Is it possible with IO::Socket::INET at all to give the server a second, maybe third IP? I'm not that experienced with this module/socket programming. I googled around but couldn't find any reference to the solution of this problem (neither did I find someone mention this problem - it seems I'm the only one who isn't able to solve this - maybe I have overlooked something really obvious?) So, if someone ...

  1. #1

    Default IO::Socket::INET - Listen on exactly two IPs the same time?

    Hi there,

    I'm just writing some little perl-server using IO:Socket::INET.

    Now, I would like to make the server listen to more than one IP
    without listening to ALL IPs (0.0.0.0). Is it possible with
    IO::Socket::INET at all to give the server a second, maybe third IP?

    I'm not that experienced with this module/socket programming. I
    googled around but couldn't find any reference to the solution of this
    problem (neither did I find someone mention this problem - it seems
    I'm the only one who isn't able to solve this - maybe I have
    overlooked something really obvious?)

    So, if someone has an idea how to get it working that way, please drop
    me a hint.

    Thanks in advance,
    Kai
    Kai Guest

  2. #2

    Default Re: IO::Socket::INET - Listen on exactly two IPs the same time?

    >>>>> "KB" == Kai Bleek <de> writes:

    KB> Now, I would like to make the server listen to more than one IP
    KB> without listening to ALL IPs (0.0.0.0). Is it possible with
    KB> IO::Socket::INET at all to give the server a second, maybe third IP?

    the socket system only allows binding to one IP/port pair or wildcarding
    any IP with a single port.

    KB> So, if someone has an idea how to get it working that way, please drop
    KB> me a hint.

    the easiest way would be to listen on each desired IP with the same port
    and use an event loop or io::select to handle the multiple listen
    sockets. once you get a connected socket you can treat them all the same
    if needed or differently based on the listen IP. you can get the listen
    IP from the socket with the getsockaddr call

    uri

    --
    Uri Guttman ------ com -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guest

  3. #3

    Default Re: IO::Socket::INET - Listen on exactly two IPs the same time?

    >>>>> "KB" == Kai Bleek <de> writes:
     [/ref]

    KB> Hm, well, that's a pity.

    note that this is not a perl restriction but one that came with the
    original BSD socket API. the whole socket/bind/listen api is geared
    towards one address and would have been very ugly if it supported
    multiple addresses. using select on those multiple sockets is not
    difficult and works around the problem nicely. you would want select to
    be used in any case for any proper server so this adds very little code
    to listen to more than one address on the same port.



    KB> # Adding to select:
    KB> my $read_set = new IO::Select();
    KB> $read_set->add($server_remote);
    KB> $read_set->add($server_local);

    KB> # entering loop
    KB> while (1) {
    KB> my select_set = $read_set->can_read;
    KB> foreach my $server (select_set) {
    KB> # distinguish between socket-IPs
    KB> if ($server == $server_remote) {
    KB> my $connect = $server->accept();
    KB> $read_set->add($connect);
    KB> # some Code...
    KB> $read_set->remove($connect);
    KB> $connect->close;
    KB> } elsif ($server == $server_local) {
    KB> my $connect = $server->accept();
    KB> $read_set->add($connect);
    KB> # some different code
    KB> $read_set->remove($connect);

    why do you remove the $connect when you don't add it to the io::select
    set? unless you do that elsewhere. and then you would need to check for
    a connected socket vs a listen socket.

    KB> $connect->close;
    KB> }
    KB> }
    KB> }

    there are better ways to do that. i would use the $server_local and
    $server_local objects as keys to a dispatch table hash and then dispatch
    based on what socket was returned from io::select. then the body of your
    loop is much cleaner and easier to extend just by adding entries into
    the dispatch table.

    <untested>

    $read_set->add($server_remote);
    $listen_handler{$server_remote} = \&remote_handler ;

    $read_set->add($server_local);
    $listen_handler{$server_local} = \&local_handler ;

    # entering loop
    while (1) {
    my select_set = $read_set->can_read;
    foreach my $server (select_set) {

    my $connect = $server->accept();
    my $handler = $listen_handler{$server} ;

    # here you could check if it is a listen socket or a connected one by
    #seeing if you got a handler for it.

    $handler->( $connect ) ;
    $connect->close;
    }


    uri

    --
    Uri Guttman ------ com -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guest

  4. #4

    Default Re: IO::Socket::INET - Listen on exactly two IPs the same time?

    Hi again,
     

    well - guess you're right about that - some artefact from my figuring
    out how to use IO::Select.
     

    I couldn't quite get along with the dipatch tables. Since I want to
    fork any connect as soon as it hits the server, my loop now looks like
    this:

    while (1) {
    my select_set = $read_set->can_read;
    foreach my $server (select_set) {
    fork_connect($server);
    }
    }

    Quite clearly arranged, isn't it? In the forking code I built
    something one would use a "case"-contruct for if it were not perl
    we're using:

    if ($childpid == 0) {
    if ("$server_ip" eq "$ini_ref->{'section'}->{'LOCAL_ADDRESS'}") {
    remote_connect($connect);
    } elsif ("$server_ip" eq "127.0.0.1") {
    local_connect($connect);
    } else {
    die "Connect from undef IP!\n";
    }
    }

    Not the most elegant way I guess, but it works for now.
    Thanks again for the help! I keep that dispatch table alternative in
    mind for later improvements.

    Kai
    Kai Guest

  5. #5

    Default Re: IO::Socket::INET - Listen on exactly two IPs the same time?

    have you just invented a super new lan card that runs two ip addresses at
    once ?


    Andrew Guest

  6. #6

    Default Re: IO::Socket::INET - Listen on exactly two IPs the same time?

    >>>>> "AR\" == Andrew Rich \(VK4TEC\) <Andrew> writes:

    AR\> have you just invented a super new lan card that runs two ip addresses at
    AR\> once ?

    no. he is probably using an IP alias technique supported on most
    OSs. actually it seems he was separating internal (localhost) and
    external connections which amounts the the same problem of listening on
    more then one IP address. and for your information, lan cards listen to
    mac (ethernet) addresses and not IP addresses.

    uri

    --
    Uri Guttman ------ com -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guest

  7. #7

    Default Re: IO::Socket::INET - Listen on exactly two IPs the same time?

    Uri Guttman <com> wrote in message news:<sysarch.com>... [/ref]
    >
    > AR\> have you just invented a super new lan card that runs two ip addresses at
    > AR\> once ?
    >
    > no. he is probably using an IP alias technique supported on most
    > OSs. actually it seems he was separating internal (localhost) and
    > external connections which amounts the the same problem of listening on
    > more then one IP address. and for your information, lan cards listen to
    > mac (ethernet) addresses and not IP addresses.[/ref]

    yes - you are right, in the end I will have several IPs added as
    virtual interfaces upon the main interface (eth0:0, eth0:1). But this
    has nothing to do with my select-prob, as you stated and what could be
    read in my previous posts, I just wanted to distinguish between local
    and remote connects. Which - btw - I have successfully realised
    (including forks and shared memory variables (storable +
    ipc::sharelite)) by now using a dispatch table, following your earlier
    suggestion.

    Regards,
    Kai
    Kai Guest

Similar Threads

  1. IO::Socket::INET hanging if packets are droped
    By leoh in forum PERL Modules
    Replies: 3
    Last Post: August 27th, 06:13 PM
  2. Replies: 2
    Last Post: April 15th, 01:41 PM
  3. socket connect and response time
    By Christophe Chisogne in forum PHP Development
    Replies: 0
    Last Post: September 19th, 03:14 PM
  4. Pb with IO::Socket::INET and recv
    By Sébastien Cottalorda in forum PERL Miscellaneous
    Replies: 1
    Last Post: September 16th, 07:47 AM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139