OK, as a first step, here is some sample code. A simple UDP sender and receiver, using the basic Socket module. These are blocking (hmm...is UDP send blocking? I'd expect the packet to simply be discarded if there was a local send buffer and it was full).
UDP receiver:
#!/usr/bin/perl
use strict;
use warnings;
use Socket;
main(@ARGV);
exit 0;
sub main {
my $listen_sock;
socket($listen_sock, PF_INET, SOCK_DGRAM, getprotobyname('udp'))
or die("Can't create socket : $!");
my $port = 1025;
bind($listen_sock, sockaddr_in($port, INADDR_ANY))
or die("Can't bind socket to port $port");
my $max_packet_size = 65536;
my $buffer;
while (1) {
my $sender = recv($listen_sock, $buffer, $max_packet_size, 0);
my ($sender_port, $sender_ip) = sockaddr_in($sender);
$sender_ip = inet_ntoa($sender_ip);
print "Received ", length $buffer,
" bytes from $sender_ip:$sender_port", "\n";
}
}
and the sender:
#!/usr/bin/perl
use strict;
use warnings;
use Socket;
main(@ARGV);
exit 0;
sub main {
my $socket;
socket($socket, PF_INET, SOCK_DGRAM, getprotobyname('udp'))
or die("Can't create socket : $!");
my $remote_port = 1025;
my $remote = sockaddr_in($remote_port, inet_aton("localhost"));
while (1) {
my $buffer = "The time is now : ", scalar localtime();
send($socket, $buffer, 0, $remote)
or die("Failed to send : $!");
sleep 1;
}
}
You should be able to run them both up on the same box and they'll talk to each other (by rendezvousing on localhost:1025).
Points of note:
- the INADDR_ANY translates to an IP address of 0.0.0.0, which means "listen on this port all local IP addresses, including 127.0.0.1". You generally want this for servers.
- try running two clients. You don't need any additional code on the server. You just see twice as many packets coming in.
- there isn't any concept of connection. The information about who sent each packet is retrieved from the return code recvcall for each packet.
There are almost certainly higher level modules on CPAN which will help you avoid some of the messing around with using sockaddr_in to pack/unpack the ip:port combinations.
You don't need to edit the listener to get things running between two hosts, just pass in the appropriate hostname/ip to inet_aton on the sender.
If you want to go non-blocking, then you're into a potentially different ball game. You'll be wanting to write your entire app from an event-driven perspective, not just the networking parts, and drinking the POE kool-aid might be a good idea in that case. |