Hi monks!

I've got a problem here. I wrote a simple non-blocking TCP server. The code listed below is extracted from the server's code. Actually, it's based on the code from O'Reilly books. It listens for incoming connections and prints everything it receives. It can process several clients at the same time. The server is written using IO::Socket and IO::Select. The problem is that $select->can_read(1) returns only when I have a newline character in the string received. How do I receive data character-by-character? I mean like a typewriter when I can see what the client is typing. The code is:

#!/usr/bin/perl -w use strict; use POSIX ; use Socket; use IO::Socket; use IO::Select; use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK O_NDELAY); my $done=0; my $select; my $server; my $connections=0; sub print_log { print strftime("%b %e %T", localtime)." "; print @_; print "\n"; } sub nonblock { my $socket = shift; my $flags; $flags = fcntl($socket, F_GETFL, 0) or print_log "Can't get flags for socket: $!\n"; fcntl($socket, F_SETFL, $flags | O_NONBLOCK) or print_log "Can't make socket nonblocking: $!\n"; } ###################################################################### +#################### $| = 1; $done=0; for my $sig (keys %SIG) { $SIG{$sig} = sub { print_log('Signal '.$_[0].' caught!'); }; } $SIG{__WARN__} = sub { print_log('WARNING: ' . $_[0]); }; $SIG{__DIE__} = sub { print_log('DIE: ' . $_[0]); }; $SIG{PIPE} = 'IGNORE'; $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{ABRT} = sub { $done = 1; }; $server = IO::Socket::INET->new(LocalAddr => "192.168.100.50", LocalPo +rt => 1024, Listen => 10, Proto => "TCP", ReuseAddr => 1 ) or die "Can't create a server socket: $@"; setsockopt($server,SOL_SOCKET,SO_LINGER,pack("l*",0,0)) || return unde +f; nonblock($server); $select = IO::Select->new($server); print_log "Started"; while(!$done) { my $client; my $rv; my $data; foreach $client ($select->can_read(1)) { if ($client == $server) { if( $connections < 5 ) { $client = $server->accept(); $connections++; $select->add($client); nonblock($client); print_log("Connected: ".$client->peerhost.":".$client- +>peerport); } else { print_log("The maximum number of simultaneous connecti +ons reached"); $client = $server->accept(); $client->shutdown(2); close($client); } } else { $data = ''; $rv = $client->recv($data, POSIX::BUFSIZ, 0); unless (defined($rv) && length $data) { print_log("Disconnected: ".$client->peerhost.":".$clie +nt->peerport); $select->remove($client); $client->shutdown(2); close $client; $connections--; next; } $data =~ s/\r//go; print $data; } } } print_log "Exit"; $server->shutdown(2); close($server);

Thank you!

In reply to A non-blocking server using 'select' calls by nikos

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.