Autoflush and new/read-line not working as expected/documented?


J

jk

Hello, I am trying to write a client-server program. Without going
into details, I'm simply reading the terminal on the server and
sending the contents to the client. I'm having an issue where neither
the client nor server are autoflushing their sockets by default, and
the client won't readlines from the server, they come as a big chunk
only after the server fails.

I have the same issue on Mac OS 10.5 (perl: 5.8.8) and Ubuntu (kernel
2.6.27) (perl: 5.10.0)

Here is some base code:
tserver.pl:
#! /usr/bin/perl -w
use strict;
use Socket;
use IO::Handle;

my $port = shift || 7890;

socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp')) or die
"socket: $!";
setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1) or die "setsock: $!";
bind(SERVER, sockaddr_in($port, INADDR_ANY)) or die "bind: $!";
listen(SERVER, SOMAXCONN) or die "listen: $!";
print "SERVER started on port $port\n";

while(not accept(CLIENT, SERVER)){}
if(fork()){
CLIENT->autoflush(1);
print CLIENT "Who is this?\n";
my $line = <CLIENT>;
print $line;
my ($rpid, $rid, $rhost) = split(/:/, $line, 3);
print CLIENT "Hello, $rid\n";
} else {
while(<> ne "quit"){}
}

wait();
close CLIENT;

tclient.pl:
#! /usr/bin/perl -w
use strict;
use Socket;
use FileHandle;

my $host = shift || 'localhost';
my $port = shift || 7890;

socket(SOCKET, PF_INET, SOCK_STREAM, getprotobyname('tcp')) or die
"socket: $!";
connect(SOCKET, sockaddr_in($port, inet_aton($host)) ) or die
"connect: $!";
SOCKET->autoflush(1);

print SOCKET "JIM:TEST:".`hostname`."\n";
print SOCKET "WHOOO\n";
print <SOCKET>;
close SOCKET or die "close: $!"


If the first autoflush is removed (in the server) no text appears on
the client if the server is killed. If the autodlush in the client is
removed, no text appears on the server. Ok, so that's not what the
docs say (sockets should autoflush, right?) but I'm sure this is a
weird, well know exception, I can live with that, but I'd like to know
what the exception is.

The other problem is that the print <SOCKET> in the client prints both
lines, and blocks until the connection is lost. The $line = <CLIENT>
line in the server correctly returns the first line sent from the
client, immediately and solely. Why doesn't the client correctly read
lines from the server, and instead block until the connection is lost.

Thanks so much for any help. I've been banging my head against my
desk for a few days looking at docs and forums. I'm sorry if this is
just some small thing I'm not seeing.

Thanks,
Jim
 
Ad

Advertisements

X

xhoster

jk said:
Hello, I am trying to write a client-server program. Without going
into details, I'm simply reading the terminal on the server and
sending the contents to the client. I'm having an issue where neither
the client nor server are autoflushing their sockets by default, and
the client won't readlines from the server, they come as a big chunk
only after the server fails.

I have the same issue on Mac OS 10.5 (perl: 5.8.8) and Ubuntu (kernel
2.6.27) (perl: 5.10.0)


socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp')) or die
"socket: $!";

I'd recommend using IO::Select, or at least using lexical file handles.

.....
If the first autoflush is removed (in the server) no text appears on
the client if the server is killed. If the autodlush in the client is
removed, no text appears on the server. Ok, so that's not what the
docs say (sockets should autoflush, right?)

The only place I know of where the docs say that is in IO::Socket. You
are not using IO::Socket. You are bypassing IO::Socket by invoking
the low-level functions directly instead, so you do not get the behavior
of IO::Socket when you are not using it.

The other problem is that the print <SOCKET> in the client prints both
lines, and blocks until the connection is lost. The $line = <CLIENT>
line in the server correctly returns the first line sent from the
client, immediately and solely. Why doesn't the client correctly read
lines from the server, and instead block until the connection is lost.

print imposes a list context on the thing expression it is to print. In
a list context, <SOCKET> will return *all* the lines on the handle, not
just the next one. In order to do that, it will block until it gets an
eof.

Perhaps you meant:
print scalar <SOCKET>;

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
Ad

Advertisements

J

jk

Well, that worked. ::face-palm:: sorry it was a stupid issue.

I misread the IO::Socket page:-\ I should prob switch this over to be
more OO once it works, huh?

Thanks so much,
Jim
 

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

Top