I was bored, so I decided to try to fix your server.
Seems to work fine, I don't see any data-loss in the testing I tried.

#!/usr/bin/perl # https://perlmonks.org/?node_id=11105232 #!/usr/bin/perl use strict; use warnings; #tcpserver.pl use IO::Select; use IO::Socket; use Data::Dumper; #use Fcntl; use constant PORT1 => 5000; use constant TIMEOUT => 10; use constant READ_LENGTH => 10; # Small to see if "buffer overflow" is handled correctly my $server_socket = new IO::Socket::INET( Listen => 1, LocalPort => PORT1, ReuseAddr => 1) or die "Can't bind server_socket: $@\n"; my $sel = IO::Select->new; $sel->add($server_socket); my %connections; # Infos and Buffers for active connections my $connID; while(1) { { # Can be used to limit the number of concurrent connections my $n = ( keys %connections ); print "$n acive connections",Dumper(\%connections); } foreach my $sock ( $sel->can_read(TIMEOUT) ) { print "sock:",( defined($connections{$sock}) ? $connections{$sock}{'id'} : ( $sock == $server_socket ? "server" : $sock )),"\n"; if( $sock == $server_socket ) # New connection { my $new = $server_socket->accept; # binmode $new; # my $flags = fcntl($new, F_GETFL, 0) or # die "[new Err] Can't get flags !$\n"; # fcntl($new , F_SETFL, $flags | O_NONBLOCK ) or # die "[new Err] Can't set flags !$\n"; # For nonblocking rea +d $sel->add($new); $connections{$new} = { ip => $new->peerhost, id => ++$connID, buf => "" }; print "server_socket->new($connections{$new}{'ip'}) Nr:$connecti +ons{$new}{'id'}\n"; next; } my ($rr, $r, $id) = (0, 0, $connections{$sock}{'id'}); my $buffer = $connections{$sock}{'buf'} ; my $buf; # $sock needs to be O_NONBLOCK # while( $rr = sysread($sock,$buf, READ_LENGTH, 0 ) ) if( $rr = sysread($sock,$buf, READ_LENGTH, 0 ) ) { print "[read ", ( $r // "undef" ), " ] '$buf'", "\n"; if( ! defined( $rr) ) # When does this happen? { # Error handler print "[Error $connections{$sock}{'ip'} id: $id]: $!\n"; # close connections? last; } $buffer .= $buf; $r += $rr; } $connections{$sock}{'buf'} = $buffer; print "[Buffer($id)] '$buffer'\n"; # if(0 and $sock->eof ) # { # print "[EOF($id)] "; # process_message( $sock); # delete $connections{$sock}; # $sel->remove($sock); # $sock->close; # next; # } if ( ! $r ) { print "[empty read($id)]\n"; process_message( $sock); delete $connections{$sock}; $sel->remove($sock); $sock->close; next; } } } sub process_message { my ( $sock ) = @_; my $filename = "rcv_$connections{$sock}{'id'}". "_$connections{$sock}{'ip'}.txt" ; open OUT, ">", $filename or die "Can not write $filename: $!"; binmode OUT; print OUT $connections{$sock}{'buf'}; close OUT; print "[save process_message] wrote $filename \n"; }

In reply to Re: Nonblocking read server by tybalt89
in thread Nonblocking read server by Carbonblack

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.