Socket Problem...

Discussion in 'Perl Misc' started by Hobbit HK, Nov 27, 2003.

  1. Hobbit HK

    Hobbit HK Guest

    I'm using AtivePerl 5.8 on WinXP and trying to do a script which
    listens and writes to the same socket (with fork of course...). Now,
    everything works great until I'm trying to write to the socket... The
    program just stucks, I think because I'm trying to read and write
    simultaneously... If I comment the read part everything goes smooth
    (except I can't get msgs :)), here's the code:

    use IO::Socket;
    $|=1;
    ($host, $port) = @ARGV;
    $port=23 if !$port;
    $sock=new IO::Socket::INET->new(PeerAddr=>$host, PeerPort=>$port,
    Proto=>'tcp') or die "Can't connect to $host on port $port! $!\n";
    $sock->autoflush(1);
    print "[Connected to $host on port $port]\n";
    die "Can't fork! $!\n" unless defined($kidpid=fork());
    if ($kidpid) {
    while (sysread($sock, $byte, 1)==1) {
    print "$byte";
    }
    kill 9, $kidpid;
    }
    else {
    while (defined($msg=<STDIN>)) {
    print "$msg\n";
    }
    }
    Hobbit HK, Nov 27, 2003
    #1
    1. Advertising

  2. Hobbit HK

    Ben Morrow Guest

    (Hobbit HK) wrote:
    > I'm using AtivePerl 5.8 on WinXP and trying to do a script which
    > listens and writes to the same socket (with fork of course...). Now,
    > everything works great until I'm trying to write to the socket... The
    > program just stucks, I think because I'm trying to read and write
    > simultaneously... If I comment the read part everything goes smooth
    > (except I can't get msgs :)), here's the code:
    >
    > use IO::Socket;
    > $|=1;
    > ($host, $port) = @ARGV;
    > $port=23 if !$port;
    > $sock=new IO::Socket::INET->new(PeerAddr=>$host, PeerPort=>$port,
    > Proto=>'tcp') or die "Can't connect to $host on port $port! $!\n";
    > $sock->autoflush(1);
    > print "[Connected to $host on port $port]\n";
    > die "Can't fork! $!\n" unless defined($kidpid=fork());
    > if ($kidpid) {
    > while (sysread($sock, $byte, 1)==1) {


    Why not just use <$sock>? Possibly with '$/ = \1;'.

    > print "$byte";


    You don't need to quote this.

    > }
    > kill 9, $kidpid;


    kill does not do what you think it does under Win32. See perlport.

    > }
    > else {
    > while (defined($msg=<STDIN>)) {
    > print "$msg\n";


    Don't you mean 'print $sock "$msg\n";'?

    > }
    > }


    What are you trying to do here? Is there even anything listening on
    port 23 of the machine you are talking to?

    Ben

    --
    The cosmos, at best, is like a rubbish heap scattered at random.
    - Heraclitus
    Ben Morrow, Nov 27, 2003
    #2
    1. Advertising

  3. Hobbit HK

    Hobbit HK Guest

    I'm not using <$sock> because I want to also get messages that doesn't
    end with a newline, any didn't want to play with $/...
    print "$byte" - I know I don't have to quote this, but it looks better
    :)
    Oh and about that "print $msg" instead of "print $sock $msg", I tried
    this to see if the program stucks (it doesn't) and forgot to replace
    it back...

    BTW I'll check about the kill thing, thanks :)
    Hobbit HK, Nov 27, 2003
    #3
  4. Hobbit HK

    Ben Morrow Guest

    [please quote (with attribution) so people have some idea of what you
    are replying to]

    (Hobbit HK) wrote:
    > Ben Morrow wrote:
    > > wrote:
    > > > [something using sysread]

    > >
    > > Why not just use <$sock>?

    >
    > I'm not using <$sock> because I want to also get messages that doesn't
    > end with a newline, any didn't want to play with $/...


    That is not a good reason. Reading a byte at a time, *espscially* with
    sysread, is very inefficient. Learn how to use $/ (and $\).

    You presumably have some way of delimiting messages?

    > > > print "$byte";

    > >
    > > You don't need to quote that.

    >
    > print "$byte" - I know I don't have to quote this, but it looks better
    > :)


    No it doesn't. It looks more confusing, and leads the reader to think
    that either you don't know what you're doing or there's something
    clever going on that he hasn't noticed. Both waste our time: don't do
    it.

    > > > print $msg;

    > >
    > > Don't you mean 'print $sock $msg;'?

    >
    > Oh and about that "print $msg" instead of "print $sock $msg", I tried
    > this to see if the program stucks (it doesn't) and forgot to replace
    > it back...


    Again, wasting our time. People do not take kindly to having their
    time wasted by those asking for help.

    > BTW I'll check about the kill thing, thanks :)


    I suspect it may not help you... have you tried connecting to the
    relevant port with telnet, or with PuTTY in 'raw' mode, to check if
    you actually get anything echoed back?

    Ben

    --
    Musica Dei donum optimi, trahit homines, trahit deos. |
    Musica truces mollit animos, tristesque mentes erigit. |
    Musica vel ipsas arbores et horridas movet feras. |
    Ben Morrow, Nov 27, 2003
    #4
  5. Hobbit HK

    Hobbit HK Guest

    Ben Morrow <> wrote in message:
    > I suspect it may not help you... have you tried connecting to the
    > relevant port with telnet, or with PuTTY in 'raw' mode, to check if
    > you actually get anything echoed back?
    >
    > Ben


    Yeah I also connected with telnet, and there's something listening and
    I can talk to it... I said before, I *can* get messeges until I'm
    trying to send ones at the same time, that's when the program stucks
    and that's my problem...
    Hobbit HK, Nov 28, 2003
    #5
  6. Hobbit HK

    Ben Morrow Guest

    (Hobbit HK) wrote:
    >I *can* get messeges until I'm
    > trying to send ones at the same time, that's when the program stucks
    > and that's my problem...


    My next guess is then that
    1. fork under Win32 actually creates a thread, not a process.
    2. The reader starts first, and does a sysread, which does a
    read(2), which blocks, and
    3. winXP is truly dumb and blocks all threads of a process when one
    of them enters a blocking syscall, so
    4. the whole program stops waiting for something to read.

    The answer to this is *NOT* to use sysread, but to use <$sock>, as I
    said in the first place (for different reasons). Although if <$sock>
    does a blocking fread(3)[1], which then does a blocking read(2),
    you're back where you were... to which the only answer is to learn how
    to do non-blocking IO properly, probably with IO::Select (and not fork
    at all, which is generally a good idea under win32 anyway).

    Ben

    [1] or PerlIO::perlio equivalent, of course.

    --
    If you put all the prophets, | You'd have so much more reason
    Mystics and saints | Than ever was born
    In one room together, | Out of all of the conflicts of time.
    |----------------+---------------| The Levellers, 'Believers'
    Ben Morrow, Nov 28, 2003
    #6
    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,770
    Mark Wooding
    Jan 27, 2009
  2. Jean-Paul Calderone
    Replies:
    0
    Views:
    950
    Jean-Paul Calderone
    Jan 27, 2009
  3. Laszlo Nagy
    Replies:
    0
    Views:
    532
    Laszlo Nagy
    Feb 1, 2009
  4. Steve Holden
    Replies:
    0
    Views:
    649
    Steve Holden
    Feb 1, 2009
  5. Steve Holden
    Replies:
    1
    Views:
    704
Loading...

Share This Page