Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Socket Problem...

Reply
Thread Tools

Socket Problem...

 
 
Hobbit HK
Guest
Posts: n/a
 
      11-27-2003
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";
}
}
 
Reply With Quote
 
 
 
 
Ben Morrow
Guest
Posts: n/a
 
      11-27-2003

http://www.velocityreviews.com/forums/(E-Mail Removed) (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
(E-Mail Removed)
 
Reply With Quote
 
 
 
 
Hobbit HK
Guest
Posts: n/a
 
      11-27-2003
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
 
Reply With Quote
 
Ben Morrow
Guest
Posts: n/a
 
      11-27-2003
[please quote (with attribution) so people have some idea of what you
are replying to]

(E-Mail Removed) (Hobbit HK) wrote:
> Ben Morrow wrote:
> > (E-Mail Removed) 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. | (E-Mail Removed)
Musica vel ipsas arbores et horridas movet feras. |
 
Reply With Quote
 
Hobbit HK
Guest
Posts: n/a
 
      11-28-2003
Ben Morrow <(E-Mail Removed)> 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...
 
Reply With Quote
 
Ben Morrow
Guest
Posts: n/a
 
      11-28-2003

(E-Mail Removed) (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:erlio 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.
(E-Mail Removed) |----------------+---------------| The Levellers, 'Believers'
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: socket.unbind or socket.unlisten? - socket.error: (48, 'Addressalready in use') Steve Holden Python 1 02-03-2009 06:20 AM
Re: socket.unbind or socket.unlisten? - socket.error: (48, 'Addressalready in use') Steve Holden Python 0 02-01-2009 12:45 PM
Re: socket.unbind or socket.unlisten? - socket.error: (48, 'Addressalready in use') Laszlo Nagy Python 0 02-01-2009 07:37 AM
socket.unbind or socket.unlisten? - socket.error: (48, 'Addressalready in use') Laszlo Nagy Python 1 01-27-2009 05:05 PM
Re: socket.unbind or socket.unlisten? - socket.error: (48,'Address already in use') Jean-Paul Calderone Python 0 01-27-2009 01:41 PM



Advertisments