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

I'm thinking about doing a simple UDP Server/Client program to improve my rather weak perl abilities.
I basically choose UDP over TCP/IP because I haven't got the hang on threading/forking, which seems to be
necessary when you want to do a multi-client TCP/IP server.

But with UDP I stumbled across another problem. Since data could be received in any
order from any user I need to sort the input and work through it.

Now I thought of a loop that does the following for every incoming packet :

- Identify which user sent the packet (So they would need to contain something like header data)
- Check which number this packet is in a row of packets by the same user (03 of 07 for example)
- Put the packet in some nested data structure
- Check whether the packet row of some user is completed :

- if yes -> echo the packets to the other users
- if no -> next loop

Is this the (or a) "right way" to do this? Or is there a better solution (which certainly wouldn't surprise me).
Or am I missing something more fundamental?

I am thankful for any help.

Replies are listed 'Best First'.
Re: Developing an UDP chat server/client
by Aighearach (Initiate) on Jul 03, 2001 at 03:53 UTC
    I don't have an answer to the main part of your question, as I haven't used UDP, but I have an answer for something fundamental that might be missed.

    You don't need to fork or thread to use TCP efficiently. It is sometimes a good way to do it, but here is an example of another way. If you like it, read the manual pages for the packages useed. Notice in particular IO::Select.

    use IO::Socket; use IO::Select; use Tie::RefHash; #there are also lots of slower ways to keep track of + the connections ;) use POSIX; #for usefull constants my %connections; my $port = 5000; tie %connections, qw( Tie::RefHash ); # so we can use refs as hash key +s my $server = IO::Socket::INET->new( Listen => SOMAXCONN, LocalPort => $port, Reuse => 1, Proto => 'tcp', ) or die "can't open connection: $!"; $server->blocking( 0 ); my $select = IO::Select->new( $server ); while('eternity'){ foreach my $connection ( $select->can_read(60) ) { if ( $connection == $server ) { # new connection waiting my $client = $connection->accept; $client->blocking( 0 ); $select->add( $client ); $connections{$client} = time; # I like to know how long a user + has been connected, you could also set this to anything; we're just +using the key for fast lookup. } elsif ( exists $connections{$connection} ) { # user sending us data my $length = $connection->sysread(my $data,POSIX::BUFSIZ); if (defined $length && length $data) { print "got '$data' from ",$connection->peerhost,':',$conne +ction->peerport,"\n"; } else { # No data, probably EOF or an error, so close $select->remove( $connection ); delete $connections{$connection}; } } }

    --
    Snazzy tagline here