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++;
}
}
|