Problem with IO::Socket

Discussion in 'Perl Misc' started by Martin Kissner, Feb 16, 2005.

  1. Hello group,

    I am trying to use a script from the book "Networkprogramming with Perl"
    by Lincoln D. Stein.

    ----
    #!/usr/bin/perl

    use warnings;
    use strict;

    use IO::Socket;

    my $server = shift;
    my $fh = IO::Socket::INET->new($server);
    my $line = <$fh>;
    print $line;
    ----

    It is supposed to read the first line from a remote server's welcome
    message.

    % ./lgetr.pl wuarchive.wustl.edu:daytime
    is supposed to output the current date of that server.

    % ./lgetr.pl wuarchive.wustl.edu:ftp
    should print the welcome message of the ftp service on
    wuarchive.wustl.edu

    % ./lgetr.pl mail.hotmail.com:smtp
    should print the welcome message of the smtp-server on mail.motmail.com

    and so on.
    In my case the script hangs infinitely without any output.
    I have even tried my local smtp server wuth the sam result.

    What could be wrong?
    Any help will be appreciated.

    Regards
    Martin

    --
    perl -e 'print 7.74.117.115.116.11.32.13.97.110.111.116.104.101.114.11
    ..32.13.112.101.114.108.11.32.13.104.97.99.107.101.114.10.7'
     
    Martin Kissner, Feb 16, 2005
    #1
    1. Advertising

  2. Martin Kissner <> wrote in
    news::

    > What could be wrong?


    I am not sure.

    > Any help will be appreciated.


    FWIW, the services you are trying

    1) May not be enabled on the computers you have tried
    2) May be behind a firewall
    3) May require prior authentication

    Sinan
     
    A. Sinan Unur, Feb 16, 2005
    #2
    1. Advertising

  3. A. Sinan Unur wrote :
    > Martin Kissner <> wrote in
    > news::
    >
    >
    > FWIW, the services you are trying
    >
    > 1) May not be enabled on the computers you have tried
    > 2) May be behind a firewall
    > 3) May require prior authentication


    Thank you for your response, Sinan.

    After I had written my answer (pointing out what I have tried to exclude
    the reasons you mentioned) I tried using the port numbers instead of the
    service name.
    This finally worked and leads me to the next question:

    Why doesn't the script (or the Perl interpreter) look up the portnumber
    in /etc/services. Telnet works properly with given servicenames.

    Regards
    Martin

    --
    perl -e 'print 7.74.117.115.116.11.32.13.97.110.111.116.104.101.114.11
    ..32.13.112.101.114.108.11.32.13.104.97.99.107.101.114.10.7'
     
    Martin Kissner, Feb 16, 2005
    #3
  4. Martin Kissner

    phaylon Guest

    Martin Kissner wrote:

    > Why doesn't the script (or the Perl interpreter) look up the portnumber in
    > /etc/services. Telnet works properly with given servicenames.


    - perl (lc) is not only for *ixoid systems.
    - telnet is programmed to do so.
    - perl can be programmed to do so.
    - You can program perl to do so.

    --
    http://www.dunkelheit.at/
    That is not dead, which can eternal lie,
    and with strange aeons even death may die.
    -- H.P. Lovecraft
     
    phaylon, Feb 16, 2005
    #4
  5. Martin Kissner

    Guest

    Martin Kissner <> wrote:
    > Why doesn't the script (or the Perl interpreter) look up the portnumber
    > in /etc/services. Telnet works properly with given servicenames.


    perldoc -f getservbyname

    perl -e 'print join(", ", getservbyname ("telnet", "tcp")), ".\n"'

    Chris
     
    , Feb 16, 2005
    #5
  6. phaylon wrote :
    > Martin Kissner wrote:
    >
    >> Why doesn't the script (or the Perl interpreter) look up the portnumber in
    >> /etc/services. Telnet works properly with given servicenames.

    >
    > - perl (lc) is not only for *ixoid systems.
    > - telnet is programmed to do so.
    > - perl can be programmed to do so.
    > - You can program perl to do so.


    Well, to be honest, I am just beginning with networkprogramming with
    Perl.
    That's why I am reading the book and at this point the above does not
    really help.

    It is the second example in the book (the first one reads one line
    from a file) and is supposed to work without any preparations and also
    on windows and classic Mac OS.

    Maybe perl can be programmed to do so (I am sure it can), but at this
    point, I do not want to work out my own humble solution.

    I would rather be interested if anyone out there could run the script
    successfully without any changes and with servicenames instead of
    portnumbers as it is suggested in the book.

    Regrads
    Martin

    --
    perl -e 'print 7.74.117.115.116.11.32.13.97.110.111.116.104.101.114.11
    ..32.13.112.101.114.108.11.32.13.104.97.99.107.101.114.10.7'
     
    Martin Kissner, Feb 16, 2005
    #6
  7. Martin Kissner

    phaylon Guest

    Martin Kissner wrote:

    > I would rather be interested if anyone out there could run the script
    > successfully without any changes and with servicenames instead of
    > portnumbers as it is suggested in the book.


    A better way is to use the docs. For IO::Socket::INET it is documented,
    that

    | If the constructor is only passed a single argument, it is assumed to be
    | a PeerAddr specification.

    A few lines up, we see

    | The PeerAddr can be a hostname or the IP-address on the "xx.xx.xx.xx"
    | form. The PeerPort can be a number or a symbolic service name. The
    | service name might be followed by a number in parenthesis which is used
    | if the service is not known by the system. The PeerPort specification
    | can also be embedded in the PeerAddr by preceding it with a ":".

    --
    http://www.dunkelheit.at/

    »Better to reign in hell than to serve in heaven«
    -- John Milton, »Paradise Lost«
     
    phaylon, Feb 16, 2005
    #7
  8. phaylon wrote :
    > Martin Kissner wrote:
    >
    >> I would rather be interested if anyone out there could run the script
    >> successfully without any changes and with servicenames instead of
    >> portnumbers as it is suggested in the book.

    >
    > A better way is to use the docs. For IO::Socket::INET it is documented,
    > that


    This will not give me any information on the above question.
    btw: I did read the docs for IO::Socket::INET.
    >
    >| If the constructor is only passed a single argument, it is assumed to be
    >| a PeerAddr specification.
    >
    > A few lines up, we see
    >
    >| The PeerAddr can be a hostname or the IP-address on the "xx.xx.xx.xx"
    >| form. The PeerPort can be a number or a symbolic service name. The
    >| service name might be followed by a number in parenthesis which is used
    >| if the service is not known by the system. The PeerPort specification
    >| can also be embedded in the PeerAddr by preceding it with a ":".


    | "The PeerPort can be a number or a service name."
    I have used a service name. No contradiction to the docs so far.

    And as sugessted in the last sentence I have embedded the service name
    in the PeerAddr by preceding it with a ":".
    The service is known by the system.

    Farther, while finding the solution to my question in the first place, I
    did some testing with unexpected results, which I did not want to
    mention in my first post to keep it scarce and tidy.

    The following script did not run either unless I didn't use use the
    line, which is commented out below for creating the socket object.
    The syntax for the constructor is taken from the docs.
    The number in parantheses seems to be not used and the service name
    seems to not work although known by the system.

    -----
    #!/usr/bin/perl

    use IO::Socket;

    my $fh = IO::Socket::INET->new(PeerAddr => 'localhost:smtp(25)');
    # my $fh = IO::Socket::INET->new(PeerAddr => 'localhost:25');
    my $line = <$fh>;
    print $line;
    -----

    Also

    my $fh = IO::Socket::INET->new(PeerAddr => 'localhost',
    PeerPort => 'PeerPort(25)');

    did not work as construcor whereas

    my $fh = IO::Socket::INET->new(PeerAddr => 'localhost',
    PeerPort => '25');

    did.

    Sorry, but I still do not understand this; therefor I am still
    interested if it works for anyone else.
    If I have overseen something, please point me to it.

    Regards
    Martin

    --
    perl -e 'print 7.74.117.115.116.11.32.13.97.110.111.116.104.101.114.11
    ..32.13.112.101.114.108.11.32.13.104.97.99.107.101.114.10.7'
     
    Martin Kissner, Feb 16, 2005
    #8
  9. Martin Kissner

    Guest

    Martin Kissner <> wrote:
    > Hello group,
    >
    > I am trying to use a script from the book "Networkprogramming with Perl"
    > by Lincoln D. Stein.
    >
    > ----
    > #!/usr/bin/perl
    >
    > use warnings;
    > use strict;
    >
    > use IO::Socket;
    >
    > my $server = shift;
    > my $fh = IO::Socket::INET->new($server);


    One should probably check for success:

    my $fh = IO::Socket::INET->new($server) or die $@;

    > my $line = <$fh>;
    > print $line;
    > ----
    >
    > It is supposed to read the first line from a remote server's welcome
    > message.
    >
    > % ./lgetr.pl wuarchive.wustl.edu:daytime
    > is supposed to output the current date of that server.


    It gives me a connection refused message.

    >
    > % ./lgetr.pl wuarchive.wustl.edu:ftp
    > should print the welcome message of the ftp service on
    > wuarchive.wustl.edu


    For me, it does do that.

    > % ./lgetr.pl mail.hotmail.com:smtp
    > should print the welcome message of the smtp-server on mail.motmail.com


    the smtp-server on mail.hotmail.com doesn't seem to have a welcome
    message.

    > and so on.
    > In my case the script hangs infinitely without any output.


    The only one that hangs for me is hotmail, and given the behavior of that
    server, this is not unexpected.


    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Feb 16, 2005
    #9
  10. Martin Kissner <> wrote in
    news::

    > Sorry, but I still do not understand this; therefor I am still
    > interested if it works for anyone else.
    > If I have overseen something, please point me to it.


    I am not sure. Here is some info:

    Microsoft Windows 2000 [Version 5.00.2195]
    This is perl, v5.8.6 built for MSWin32-x86-multi-thread

    C:\> perl -MIO::Socket::INET -e "print $IO::Socket::INET::VERSION"
    1.27

    I tried your script against a variety of hosts using the service name
    'smtp'. The script worked as expected.

    You will need to give some more information regarding the system on which
    you are testing this in a clear and concise way.

    Now, you can check if perl is able to do the mapping from service names
    to port addresses on your system by running this script (from Perl docs):

    #! /usr/bin/perl

    use strict;
    use warnings;

    use Net::servent;
    my $s = getservbyname(shift) || die "no service";
    printf "port for %s is %s, aliases are %s\n",
    $s->name, $s->port, "@{$s->aliases}";

    __END__

    On the system I mentioned above, this gives me:

    C:\> perl s.pl smtp
    port for smtp is 25, aliases are mail

    C:\> perl s.pl chargen
    port for chargen is 19, aliases are ttytst source

    Exploring from here is an option.

    Sinan
     
    A. Sinan Unur, Feb 16, 2005
    #10
  11. wrote :
    > Martin Kissner <> wrote:


    >> my $fh = IO::Socket::INET->new($server);

    >
    > One should probably check for success:


    Yes, that's probably true.

    > my $fh = IO::Socket::INET->new($server) or die $@;


    >> % ./lgetr.pl wuarchive.wustl.edu:daytime
    >> is supposed to output the current date of that server.

    >
    > It gives me a connection refused message.


    The book is from 2002; the service is discontinued, I guess.
    But it proves, that the script tried to connect.

    >> % ./lgetr.pl wuarchive.wustl.edu:ftp
    >> should print the welcome message of the ftp service on
    >> wuarchive.wustl.edu

    >
    > For me, it does do that.


    Thank you for that information.
    What is your OS? Mine is Darwin 7.8 (Mac OS X)
    Which Version of Perl are you using. I am using Perl 5.8.1

    >> % ./lgetr.pl mail.hotmail.com:smtp
    >> should print the welcome message of the smtp-server on mail.motmail.com

    >
    > the smtp-server on mail.hotmail.com doesn't seem to have a welcome
    > message.


    With telnet I get

    | 220 mc9-f7.hotmail.com Sending unsolicited commercial or bulk e-mail to
    | Microsoft's computer network is prohibited. Other restrictions are found
    | at http://privacy.msn.com/Anti-spam/. Violations will result in use of
    | equipment located in California and other states. Wed, 16 Feb 2005
    | 13:48:09 -0800

    I do still not know how to find out why it doesn't work on my system.
    Any suggestions are welcome.

    Regards
    Martin

    --
    perl -e 'print 7.74.117.115.116.11.32.13.97.110.111.116.104.101.114.11
    ..32.13.112.101.114.108.11.32.13.104.97.99.107.101.114.10.7'
     
    Martin Kissner, Feb 16, 2005
    #11
  12. Re: Problem with IO::Socket [... on Mac OS X]

    A. Sinan Unur wrote :
    > Martin Kissner <> wrote in
    > news::


    >> Sorry, but I still do not understand this; therefor I am still
    >> interested if it works for anyone else.
    >> If I have overseen something, please point me to it.

    >
    > You will need to give some more information regarding the system on which
    > you are testing this in a clear and concise way.


    Of course.
    I should have done in the first place.

    % uname -msr
    Darwin 7.8.0 Power Macintosh
    # which is Mac OS X

    % perl -v
    This is perl, v5.8.1-RC3 built for darwin-thread-multi-2level
    (with 1 registered patch, see perl -V for more detail)

    > Now, you can check if perl is able to do the mapping from service names
    > to port addresses on your system by running this script (from Perl docs):


    Thank you for the script.

    % ./test_services.pl smtp
    port for smtp is 25, aliases are

    % ./test_services.pl http
    port for http is 80, aliases are www www-http

    works optimally and makes it still more surprising that the script doesn't

    --
    perl -e 'print 7.74.117.115.116.11.32.13.97.110.111.116.104.101.114.11
    ..32.13.112.101.114.108.11.32.13.104.97.99.107.101.114.10.7'
     
    Martin Kissner, Feb 16, 2005
    #12
  13. Martin Kissner

    Guest

    Martin Kissner <> wrote:
    >
    > >> % ./lgetr.pl wuarchive.wustl.edu:ftp
    > >> should print the welcome message of the ftp service on
    > >> wuarchive.wustl.edu

    > >
    > > For me, it does do that.

    >
    > Thank you for that information.
    > What is your OS? Mine is Darwin 7.8 (Mac OS X)
    > Which Version of Perl are you using. I am using Perl 5.8.1


    Sorry, I should have included that:

    Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration:
    Platform:
    osname=linux, osvers=2.4.21-1.1931.2.393.entsmp,
    archname=i386-linux-thread-multi

    > >> % ./lgetr.pl mail.hotmail.com:smtp
    > >> should print the welcome message of the smtp-server on
    > >> mail.motmail.com

    > >
    > > the smtp-server on mail.hotmail.com doesn't seem to have a welcome
    > > message.

    >
    > With telnet I get
    >
    > | 220 mc9-f7.hotmail.com Sending unsolicited commercial or bulk e-mail to
    > | Microsoft's computer network is prohibited. Other restrictions are
    > | found at http://privacy.msn.com/Anti-spam/. Violations will result in
    > | use of equipment located in California and other states. Wed, 16 Feb
    > | 2005 13:48:09 -0800


    For me it just hung, even with telnet. Maybe it was just very slow and I
    didn't wait long enough.

    > I do still not know how to find out why it doesn't work on my system.
    > Any suggestions are welcome.


    After you added error checking, did it still hang with the first one, or
    did you get a connection refused?

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Feb 17, 2005
    #13
  14. Re: Problem with IO::Socket [... on Mac OS X]

    wrote :
    > Martin Kissner <> wrote:
    >
    >> I do still not know how to find out why it doesn't work on my system.
    >> Any suggestions are welcome.

    >
    > After you added error checking, did it still hang with the first one, or
    > did you get a connection refused?


    This morning I tried to connect to a ftp-server in my LAN and watched the
    network with tcpdump.
    There was no attempt to connect and the script hanged as it did without
    error checking.
    With a port number the script connected at once.
    With an invalid port number I got the error message as expected
    (Connection refused ... ).

    What else could I do to find the reason for this behaviour?

    Regards
    Martin

    --
    perl -e 'print 7.74.117.115.116.11.32.13.97.110.111.116.104.101.114.11
    ..32.13.112.101.114.108.11.32.13.104.97.99.107.101.114.10.7'
     
    Martin Kissner, Feb 17, 2005
    #14
  15. Martin Kissner

    Anno Siegel Guest

    Re: Problem with IO::Socket [... on Mac OS X]

    Martin Kissner <> wrote in comp.lang.perl.misc:
    > A. Sinan Unur wrote :


    > > You will need to give some more information regarding the system on which
    > > you are testing this in a clear and concise way.

    >
    > Of course.
    > I should have done in the first place.
    >
    > % uname -msr
    > Darwin 7.8.0 Power Macintosh
    > # which is Mac OS X


    Something is fishy on Darwin. I also see it hang when the service is
    given by name and reply as expected when given by port number. However,
    just *calling* getservbyname() before opening the socket makes it work
    with a name too.

    use IO::Socket;

    my $server = shift;

    if ( my ( $port) = $server =~ /:(.*)/ ) {
    # just call it
    getservbyname( $port, 'tcp') or die "getservbyname( $port)";
    }

    print "Trying $server\n";
    my $fh = IO::Socket::INET->new( $server) or die $!;
    my $line = <$fh>;
    print $line;

    __END__

    This gives the expected reply from "mail.hotmail.com:smtp". Comment out
    the call to getservbyname() and it doesn't.

    I'm not sure how Darwin deals with getservbyname(). It may use some
    netinfo devilry instead of /etc/services. The man page is ominously
    missing.

    Anno
     
    Anno Siegel, Feb 17, 2005
    #15
  16. Re: Problem with IO::Socket [... on Mac OS X]

    Anno Siegel wrote :

    > Something is fishy on Darwin.


    I guess it is.
    I will try this on FreeBSD as soon as possible.

    > I also see it hang when the service is
    > given by name and reply as expected when given by port number. However,
    > just *calling* getservbyname() before opening the socket makes it work
    > with a name too.
    >
    > use IO::Socket;
    >
    > my $server = shift;
    >
    > if ( my ( $port) = $server =~ /:(.*)/ ) {
    > # just call it
    > getservbyname( $port, 'tcp') or die "getservbyname( $port)";
    > }
    >
    > print "Trying $server\n";
    > my $fh = IO::Socket::INET->new( $server) or die $!;
    > my $line = <$fh>;
    > print $line;
    >


    Thank you for this code example. It works for me, too and examples like
    this one expand my view since I am not so experienced in Perl
    programming.

    > This gives the expected reply from "mail.hotmail.com:smtp". Comment out
    > the call to getservbyname() and it doesn't.
    >
    > I'm not sure how Darwin deals with getservbyname(). It may use some
    > netinfo devilry instead of /etc/services. The man page is ominously
    > missing.


    Te documentation to Darwin sometimes is a drag. It has become better
    with Panther, but it's still not goos enough.
    However, Darwin does use /etc/services.
    I tried by simply changing the name of a service in /etc/services.



    --
    perl -e 'print 7.74.117.115.116.11.32.13.97.110.111.116.104.101.114.11
    ..32.13.112.101.114.108.11.32.13.104.97.99.107.101.114.10.7'
     
    Martin Kissner, Feb 17, 2005
    #16
  17. Re: Problem with IO::Socket [... on Mac OS X]

    Anno Siegel wrote :

    > Something is fishy on Darwin. I also see it hang when the service is
    > given by name and reply as expected when given by port number. However,
    > just *calling* getservbyname() before opening the socket makes it work
    > with a name too.


    After I had proved that servicenames can be resolved by Perl on Mac OS X
    with the function 'getservbyname()' I was interested if I could find out
    how IO::Socket::INET gets the servicenames and how this might be
    different from 'getservbyname()'.
    As far as I can see IO::Socket::INET uses 'getservbyname()'.
    In Version 1.26 of IO::Socket::INET the conversion is done in line 58/59
    of 'INET.pm'.

    After all I tried the script once again without making any changes and
    to my very great surprise it ran flawlessly with servicenames and with
    portnumbers.
    If Anno had not seen it hang when servicenames were given, I'd probably
    doubted my mental health ;-).

    I report this not because I expect that someone could explain this
    but to give some final feedback to everybody who had to helped.

    Best regards
    Martin

    --
    perl -e 'print 7.74.117.115.116.11.32.13.97.110.111.116.104.101.114.11
    ..32.13.112.101.114.108.11.32.13.104.97.99.107.101.114.10.7'
     
    Martin Kissner, Feb 20, 2005
    #17
  18. Martin Kissner

    Anno Siegel Guest

    Re: Problem with IO::Socket [... on Mac OS X]

    Martin Kissner <> wrote in comp.lang.perl.misc:
    > Anno Siegel wrote :
    >
    > > Something is fishy on Darwin. I also see it hang when the service is
    > > given by name and reply as expected when given by port number. However,


    [...]

    > After all I tried the script once again without making any changes and
    > to my very great surprise it ran flawlessly with servicenames and with
    > portnumbers.
    > If Anno had not seen it hang when servicenames were given, I'd probably
    > doubted my mental health ;-).


    I've seen that too. It wasn't reproducible, so I dismissed it for
    the time being.

    Anno
     
    Anno Siegel, Feb 21, 2005
    #18
  19. Re: Partial solution: Problem with IO::Socket on Mac OS X

    Anno Siegel wrote :
    > Martin Kissner <> wrote in comp.lang.perl.misc:
    >> After all I tried the script once again without making any changes and
    >> to my very great surprise it ran flawlessly with servicenames and with
    >> portnumbers.
    >> If Anno had not seen it hang when servicenames were given, I'd probably
    >> doubted my mental health ;-).

    >
    > I've seen that too. It wasn't reproducible, so I dismissed it for
    > the time being.


    This turned out to be really annoying.
    This morning I tried another script from my book and it ran right away.
    After I came back from work, I woke up my computer and ran the script
    from the shell history ... and got an error or better said a warning.
    The first script (the one I posted) also didn't run any more.

    Surprising to me was, that the 'new' method sucessfully returned a socket
    object. The problem was that this socket can not be used, however.

    I finally found out, that 'IO::Socket::INET->new()' seems to open an UDP Socket
    at least sometimes on Mac OS X.

    The manual says:
    | If "Proto" is not given and you specify a symbolic "PeerPort" port,
    | then the constructor will try to derive "Proto" from the service
    | name. As a last resort "Proto" "tcp" is assumed.

    This is what I have experienced:
    As soon as the PeerPort specification is given as number it seems that 'tcp' is
    assumed in any case unless "Proto" is given.
    It seems that if "Proto" is not given in most cases the protocol is used,
    which is listed first in "/etc/services".
    On Mac OS X the udp specifications are listed before the tcp spec. in the
    services file.
    That (I guess) is the reason for the deadlocks.

    This, however, does not explain why sometimes 'tcp' is assumed on Mac OS X.
    It also doesn't explain, why 'tcp' is not assumed with services like ftp, smtp
    etc. which AFAIK can not be used with udp.
    And finally I can not find the code in Socket.pm which should be responsible
    for what I have quoted above fom the documentation.

    Is there a way to find out the reason for this unreliability?
    What would be the right address to report a -in my opinion bugy- behaviour
    like this?
    Is there a chance to fix this (or get it fixed)?

    My conclusion for now is, to always define "Proto".

    Best regards
    Martin

    --
    perl -e 'print 7.74.117.115.116.11.32.13.97.110.111.116.104.101.114.11
    ..32.13.112.101.114.108.11.32.13.104.97.99.107.101.114.10.7'
     
    Martin Kissner, Feb 21, 2005
    #19
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Laszlo Nagy
    Replies:
    1
    Views:
    4,927
    Mark Wooding
    Jan 27, 2009
  2. Jean-Paul Calderone
    Replies:
    0
    Views:
    993
    Jean-Paul Calderone
    Jan 27, 2009
  3. Laszlo Nagy
    Replies:
    0
    Views:
    566
    Laszlo Nagy
    Feb 1, 2009
  4. Steve Holden
    Replies:
    0
    Views:
    685
    Steve Holden
    Feb 1, 2009
  5. Steve Holden
    Replies:
    1
    Views:
    731
Loading...

Share This Page