Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Server waits for user input before sending text.

by thran (Novice)
on Oct 06, 2001 at 20:19 UTC ( #117216=perlquestion: print w/replies, xml ) Need Help??

thran has asked for the wisdom of the Perl Monks concerning the following question:

I want to use this server framework for a project of mine, but somehow when a client connects to it using telnet or something similar, the server just sits there and waits for the user to type any button, before sending that which he was supposed to send right away. I tried to set autoflush to 1, but that didnt seem to work either. Can anyone explain to me, what iam doing wrong? Thanks in advance!
#taken from perlnet #!/usr/bin/perl use IO::Socket; # include the select package use IO::Select; # they're counting the number of connections $nconnections_old = 0; $nconnections_new = 0; $port = 1234; $new_client = IO::Socket::INET->new(Proto=>"tcp", LocalPort=>$port, Li +sten=>$max_clients, Reuse=>1); # create a new selection and add our basic socket for incoming connect +ions $sel = IO::Select->new($new_client); while (@ready = $sel->can_read) { # for every readable socket foreach $client (@ready) { # check if it is the basic socket if ($client == $new_client) { # if it is establish new connection $add = $client->accept; # add new socket to the selection $sel->add($add); # increase number of connections $nconnections_new++; # if it is an already established connectection } else { #It waits for user input here, like an enter, or somehing before it pr +ints the string in $hey to the client.. Why?? $hey="Hey, Iam the server, how are you?"; syswrite($client, $hey, length($hey)); } } # if number of connections has changed, print it if ($nconnections_old != $nconnections_new) { print "Already $nconnections_new connection(s)\n"; $nconnections_old++; } }

Replies are listed 'Best First'.
Re: Server waits for user input before sending text.
by pjf (Curate) on Oct 07, 2001 at 01:52 UTC
    Howdy thran,

    Your problem lies in that your main loop is only checking for sockets which can be read from, rather than being written to. Your connected socket can't be read until the remote client sends some data.

    The way around this is to test for both reads and writes in your select loop, like this:

    my $readsocks = IO::Select->new($new_client); my $writesocks = IO::Select->new(); while (($readers, $writers) = IO::Select->select($readsocks,$writesock +s)) { foreach my $sock (@$readers) { # Read from a socket... # Perhaps add this socket to $writesocks. } foreach my $sock (@$writers) { # Write to a socket. } }
    This lets you look for sockets that are available for both reading and/or writing, and should eliminate the problem.

    I've included a simple re-write of the code below, updated to test for both reading and writing. It also uses strict and warnings, because you'll really want them if you're developing anything even remotely complex (like this).

    Note that the server still needs to be able to deal with connections once they've closed. You'll know when a connection has closed when select indicates it's available for reading, but when you do read you receive an empty or undefined message.

    Cheers,

    Paul

    #!/usr/bin/perl -w use strict; use IO::Socket; # include the select package use IO::Select; # they're counting the number of connections $nconnections_old = 0; my $port = 1234; my $max_clients = 0; my ($nconnections_new, $nconnections_old) = (0,0); my $new_client = IO::Socket::INET->new(Proto=>"tcp", LocalPort=>$port, + Listen=>$max_clients, Reuse=>1); # create a new selection and add our basic socket for incoming connect +ions my $readlist = IO::Select->new($new_client); my $writelist = IO::Select->new(); while (my ($readers, $writers) = IO::Select->select($readlist,$writeli +st)) { # for every readable socket foreach my $client (@$readers) { # check if it is the basic socket if ($client == $new_client) { # if it is establish new connection my $add = $client->accept; # add new socket to the selection $readlist->add($add); $writelist->add($add); # increase number of connections $nconnections_new++; } else { # Else it's an established connection trying # to talk to us, OR a socket shutting down. } } foreach my $client (@$writers) { # Print our message to clients we can write to, # if we haven't already done so. my $hey="Hey, I am the server, how are you?\n"; syswrite($client, $hey); # Remove that client from the list of clients we # want to write to, otherwise we spam them with # greetings continuously. $writelist->remove($client); } # if number of connections has changed, print it if ($nconnections_old != $nconnections_new) { print "Already $nconnections_new connection(s)\n"; $nconnections_old++; } }
Re: Server waits for user input before sending text.
by jlongino (Parson) on Oct 06, 2001 at 22:24 UTC
    I may be totally off base here, but have you tried:
    select((select(STDOUT), $| = 1)[0]); #flush STDOUT buffer
    after the syswrite?

    Update: Of course substitute your connection for STDOUT.

    "Make everything as simple as possible, but not simpler." -- Albert Einstein

Re: Server waits for user input before sending text.
by thinker (Parson) on Oct 06, 2001 at 20:56 UTC
    Hi, Try sending a newline at the end, like
    $hey="Hey, Iam the server, how are you?\n"; syswrite($client, $hey, length($hey));
    HTH thinker
      No , I tried that, but that didnt work either.. :S
Re: Server waits for user input before sending text.
by em (Scribe) on Oct 07, 2001 at 14:30 UTC
    I just read about this in Network Programming with Perl. It's written by Lincoln Stein (the author of CGI.PM). You can find out more about the book at his site.

    There's a sample script that deals with your issue by using fork. Check it out here

Re: Server waits for user input before sending text.
by em (Scribe) on Oct 07, 2001 at 14:33 UTC
    I just read about this in Network Programming with Perl. It's written by Lincoln Stein (the author of CGI.PM). You can find out more about the book at his site.

    There's a sample script that deals with your issue by using fork. Check it out here

    The book rocks, btw. If you're writing network-related code in Perl, it's an excellent resource.

    Sorry about the duplicate post. Posting at 3:30am is not a good idea. :(

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://117216]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (3)
As of 2023-10-01 10:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?