Socket Problem...

H

Hobbit HK

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";
}
}
 
B

Ben Morrow

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 said:
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
 
H

Hobbit HK

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 :)
 
B

Ben Morrow

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

Ben said:
[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" - 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.
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
 
H

Hobbit HK

Ben Morrow said:
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...
 
B

Ben Morrow

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,708
Latest member
SherleneF1

Latest Threads

Top