in reply to socket - echo server
This is not normally how you would write a multi-client server. Your code accepts a connection, waits up to 10 seconds for data to arrive, sends the data back if it arrives in time, then disconnects and goes back to wait for the next connection. This is handling clients serially. If I were to attempt 60 connections to your server but not send any data on any of those connections, any other clients would be hung for up to 10 minutes before you to timed out all of my requests.
Normally, the server socket would be included in the select set. When that socket becomes ready, you can issue an accept on it. If another socket becomes ready, you can issue a read on it. Timeout handling becomes a little more difficult.
I just hacked this up and it seems to work.
#!/usr/bin/perl -w use strict; use IO::Select; use IO::Socket; use constant ECHO_PORT => 9999; my %clients; my $count; my $srvr = IO::Socket::INET->new(Proto=>'tcp', LocalPort=>ECHO_PORT, Listen=>SOMAXCONN, Reuse=>1) or die "Error creating server socket: $!"; $srvr->autoflush(1); my $sel = IO::Select->new($srvr); while (1) { my @rdy = $sel->can_read(1); if (scalar @rdy == 0) { # remove timed out clients my $t = time(); for my $cli (keys %clients) { if ($clients{$cli}{timeout} <= $t) { $sel->remove($clients{$cli}{conn}); $clients{$cli}{conn}->close(); delete $clients{$cli}; } } } for my $cli (@rdy) { if ($cli == $srvr) { my $cli = $srvr->accept; unless ($cli) { die "Error accepting client connection: $!\n"; next; } $clients{$cli}{conn} = $cli; $clients{$cli}{timeout} = time() + 10; $sel->add($cli); } else { my $buffer; if (sysread ($cli,$buffer,1024)) { syswrite($cli,$buffer); } else { warn "Error reading from client: $!\n"; } $sel->remove($cli); $cli->close(); delete $clients{$cli}; } } }
--- print map { my ($m)=1<<hex($_)&11?' ':''; $m.=substr('AHJPacehklnorstu',hex($_),1) } split //,'2fde0abe76c36c914586c';
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Re: socket - echo server
by vek (Prior) on Jan 18, 2003 at 16:33 UTC |