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


I'm trying to make a client server socket application because I want to change some communication apis based in PHP in a centos7 server that sadly now it becomes very slow, I made some tests with perl as I'm new with this language and I'm very glad with the results.

I successfuly made a script to parse some mail logs and import it to database for filtering purposes and I can say that it is by far the faster (in cpu resources) than other languages, but now, what I want to do is:

Actually I have in each server (more that 100 servers) with a php script that runs every minute and introduces some data to the central server api. At the begining it was great, very easy and was working fine in PHP but now I'm facing some issues related to php + big file reading and parsing, thing that is done great in perl.

I tested a simple script posted here that can handle multiple clients and do the job very good, but for some reason, sometimes the server brokes with aparently no error message and nothing to trace and as it will be used in production servers I don't want it to silently stop working.

When I connect to socket I can see server is accepting the request and do it all fine, but if I start to send data at sometime if I send a lot of data it breaks.

Here is the code I used:
#!/usr/bin/perl use strict; use warnings; use threads; use IO::Socket::IP; my $host = ''; my $port = '1337'; my $proto = 'tcp'; my $debug = 1; my $output = 'report.txt'; my @allowed_ips = (''); sub Main { # flush after every write $| = 1; my ($socket, $client_socket); # Bind to listening address and port $socket = new IO::Socket::INET( LocalHost => $host, LocalPort => $port, Proto => $proto, Listen => 5, Reuse => 1 ) or die "ERROR > Could not open socket: ".$!."\n"; print "INFO > Waiting for client connections on tcp:[$host]:$port +...\n"; my @clients = (); while(1){ # Waiting for new client connection $client_socket = $socket->accept(); # Push new client connection to it's own thread push (@clients, threads->create(\&clientHandler, $client_socke +t)); foreach(@clients){ if($_->is_joinable()) { $_->join(); } } } $socket->close(); return 1; } sub clientHandler { # Socket is passed to thread as first (and only) argument. my ($client_socket) = @_; # Create hash for user connection/session information and set init +ial connection information. my %user = (); $user{peer_address} = $client_socket->peerhost(); $user{peer_port} = $client_socket->peerport(); unless (client_allowed($user{peer_address})){ print $client_socket "Server > Connection denied.\n"; print "WARN > Connection from $user{peer_address}:$user{peer_ +port} denied by IP policy.\n"; $client_socket->shutdown(2); $client_socket->close(); threads->exit(); } print "INFO > Client ".$user{peer_address}.":".$user{peer_port}." + has been conected.\n"; # Let client know that server is ready for commands. print $client_socket "Server > Welcome to raClus-Server $user{peer +_address}\n$user{peer_address}> "; # Listen for commands while client socket remains open while(my $buffer = <$client_socket>){ # Accept the command `PING` from client with optional argument +s if($buffer =~ /^PING(\s|$)/i) { print $client_socket "Server > Pong!\n"; } # Accept the command `HELLO` from client with optional argumen +ts if($buffer =~ /^HELLO(\s|$)/i){ print $client_socket "Server > Hello!\n"; print $client_socket "Server > Your IP:\t".$user{peer_addr +ess}."\n"; print $client_socket "Server > Your Port:\t".$user{peer_po +rt}."\n"; } # This will terminate the client connection to the server if($buffer =~ /^QUIT(\s|$)/i){ # Print to client, and print to STDOUT then exit client co +nnection & thread print $client_socket "Server > GOODBYE\n"; print "INFO > Client ".$user{peer_address}.":".$user{peer +_port}." has been disconnected.\n"; $client_socket->shutdown(2); threads->exit(); } print "DEBUG > $buffer" if $debug; print $client_socket "$user{peer_address} > "; } print "INFO > Client ".$user{peer_address}.":".$user{peer_port}." + has been disconnected.\n"; # Client has exited so thread should exit too threads->exit(); } sub client_allowed { my $client_ip = shift; return grep { $_ eq $client_ip || $_ eq '0/0' || $_ eq '' + } @allowed_ips; } # Start the Main loop Main();
Any help will be appreciated