Multithreading and sockets blocking I/O on Win32

Discussion in 'Perl Misc' started by Dragos D, Aug 17, 2003.

  1. Dragos D

    Dragos D Guest

    Hello!

    I'm posting here as a last, desperate attempt to solve a problems that made
    me pull my hair off: I want to create (as a cradle for further development)
    a simple, basic, transparent proxy server for any protocol, using threads
    (the new model, "use threads" instead of "use Thread"). That is, only one
    client will connect to the server, the server will connect in turn to a
    remote server, then it will relay data from the remote server to the client,
    and from the client to the remote server.

    This has to run on Windows, so I'm using ActiveState Perl 5.0.8 build 805
    running under Windows 98 SE.

    After accepting a connection, the program launches one thread to read data
    from the client and send it to the server, and another thread to read data
    from the remote server and send it to the client. The idea is NOT to
    interpret data in any way, just relay it until the client and the server
    close the connection.

    I chose as an example connecting to a POP3 server, pop.lycos.co.uk. OK, so I
    run it, then fire up a telnet client and connect to localhost:8080. The
    telnet client correctly sees the POP3 server's greeting message (+OK...),
    then I type "hi" (an invalid command, which should produce a "-ERR" response)
    but... the "hi" is NOT sent (packet sniffer reveals no traffic after the
    +OK response). Accordingly, the last line I see on STDERR is:

    TO remote: [hi] at ...

    Suggesting that the "print {$remoteServer} $lineout, $EOL;" hangs the script.

    Can someone please confirm this behaviour on Windows or infirm it on *nix?

    And, if someone could point out what I'm doing wrong, I'd be the most
    grateful.


    Thanks for your time,
    Dragos



    #! perl -w

    use IO::Socket;
    use threads;
    use strict;

    my $EOL = "\015\012"; # the standard Internet line terminator
    my $port = 8080;

    my $listener = IO::Socket::INET->new(LocalPort=>$port, Listen=>5, Reuse=>1);
    my $client=$listener->accept or die "Can't accept, $!";

    my $remoteServer = IO::Socket::INET->new('pop.lycos.co.uk:110')
    or die "Can't connect to remote server, $!";

    my $threadTO = threads->create("ThreadTOremote");
    my $threadFROM = threads->create("ThreadFROMremote");

    $threadTO->join;
    $threadFROM->join;

    sub ThreadTOremote
    { my $lineout;
    while (defined($lineout=<$client>))
    { $lineout=~s/(\x0D\x0A|\x0A\x0D|\x0D|\x0A|)$//; # strip any line ending
    warn 'TO remote: [', $lineout, ']'; # <-- BLOCKS HERE !!!
    print {$remoteServer} $lineout, $EOL;
    warn 'After print TO remoteServer'; # this never gets displayed
    }
    }

    sub ThreadFROMremote
    { my $linein;
    while (defined($linein=<$remoteServer>))
    { $linein=~s/(\x0D\x0A|\x0A\x0D|\x0D|\x0A|)$//; # strip any line ending
    warn 'FROM remote TO client: [', $linein, ']';
    print {$client} $linein, $EOL;
    warn 'After print to client';
    }
    }
     
    Dragos D, Aug 17, 2003
    #1
    1. Advertising

  2. Dragos D <> wrote:
    DD> Hello!

    DD> I'm posting here as a last, desperate attempt to solve a problems that made
    DD> me pull my hair off: I want to create (as a cradle for further development)
    DD> a simple, basic, transparent proxy server for any protocol, using threads
    DD> (the new model, "use threads" instead of "use Thread"). That is, only one
    DD> client will connect to the server, the server will connect in turn to a
    DD> remote server, then it will relay data from the remote server to the client,
    DD> and from the client to the remote server.

    DD> This has to run on Windows, so I'm using ActiveState Perl 5.0.8 build 805
    DD> running under Windows 98 SE.

    DD> After accepting a connection, the program launches one thread to read data
    DD> from the client and send it to the server, and another thread to read data
    DD> from the remote server and send it to the client. The idea is NOT to
    DD> interpret data in any way, just relay it until the client and the server
    DD> close the connection.

    DD> I chose as an example connecting to a POP3 server, pop.lycos.co.uk. OK, so I
    DD> run it, then fire up a telnet client and connect to localhost:8080. The
    DD> telnet client correctly sees the POP3 server's greeting message (+OK...),
    DD> then I type "hi" (an invalid command, which should produce a "-ERR" response)
    DD> but... the "hi" is NOT sent (packet sniffer reveals no traffic after the
    DD> +OK response). Accordingly, the last line I see on STDERR is:

    DD> TO remote: [hi] at ...

    DD> Suggesting that the "print {$remoteServer} $lineout, $EOL;" hangs the script.

    DD> Can someone please confirm this behaviour on Windows or infirm it on *nix?

    It works on Linux.

    $ ./foo
    FROM remote TO client: [+OK POP3 server ready <>] at ./foo line 39, <GEN2> line 1.
    After print to client at ./foo line 41, <GEN2> line 1.
    TO remote: [hi] at ./foo line 27, <GEN1> line 1.
    After print TO remoteServer at ./foo line 30, <GEN1> line 1.
    FROM remote TO client: [-ERR Unknown command.] at ./foo line 39, <GEN2> line 2.
    After print to client at ./foo line 41, <GEN2> line 2.

    $ telnet localhost 8080
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    +OK POP3 server ready <>
    hi
    -ERR Unknown command.
    Connection closed by foreign host.

    Regards,

    Nicholas

    --
    "Why shouldn't I top-post?" http://www.aglami.com/tpfaq.html
    "Meanings are another story." http://www.ifas.org/wa/glossolalia.html
     
    Nicholas Dronen, Aug 18, 2003
    #2
    1. Advertising

  3. Dragos D

    Dragos D Guest

    (James Willmore) wrote in message news:<>...
    >
    > I think the OP made a small error in typing - he does have 5.8.0.
    > Build 805 is for version 5.8.0 - however, the latest is 806.


    Indeed, it was a typo, I had 5.8.0 build 805.

    > See:
    > http://downloads.activestate.com/ActivePerl/Windows/5.8/
    > to verify


    I'd be damned!

    I downloaded build 806 and it worked!!!

    The very same program I've posted here worked!

    Build 806 rulez :)


    Thanks to you all,
    Dragos
     
    Dragos D, Aug 18, 2003
    #3
    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. Hendra Gunawan
    Replies:
    1
    Views:
    13,065
    Allan Herriman
    Apr 8, 2004
  2. Tero Saarni
    Replies:
    2
    Views:
    304
    Tero Saarni
    Aug 7, 2003
  3. Tim Black
    Replies:
    1
    Views:
    1,374
    Alan Kennedy
    Aug 3, 2004
  4. nukleus
    Replies:
    14
    Views:
    910
    Chris Uppal
    Jan 22, 2007
  5. gabriele renzi

    Non-Blocking sockets on win32 patch

    gabriele renzi, Sep 1, 2004, in forum: Ruby
    Replies:
    1
    Views:
    98
    Jean-Francois Nadeau
    Sep 1, 2004
Loading...

Share This Page