| Net-RTP documentation | Contained in the Net-RTP distribution. |
Net::RTP - Send and receive RTP packets (RFC3550)
use Net::RTP; my $rtp = new Net::RTP( LocalPort=>5170, LocalAddr=>'233.122.227.171' ); my $packet = $rtp->recv(); print "Payload type: ".$packet->payload_type()."\n";
The Net::RTP module subclasses IO::Socket::Multicast6 to enable
you to manipulate multicast groups. The multicast additions are
optional, so you may also send and recieve unicast packets.
The new() method is the constructor for the Net::RTP class. It takes the same arguments as IO::Socket::INET, however the Proto argument defaults to "udp", which is more appropriate for RTP.
The Net::RTP super-class used will depend on what is available on your system it will try and use one of the following (in order of preference) :
IO::Socket::Multicast6 (IPv4 and IPv6 unicast and multicast) IO::Socket::Multicast (IPv4 unicast and multicast) IO::Socket::INET6 (IPv4 and IPv6 unicast) IO::Socket::INET (IPv4 unicast)
If LocalAddr looks like a multicast address, then Net::RTP will automatically try and join that multicast group for you.
Blocks and waits for an RTP packet to arrive on the UDP socket.
The read $size defaults to 2048 which is usually big enough to read
an entire RTP packet (as it is advisable that packets are less than
the Ethernet MTU).
Returns a Net::RTP::Packet object or undef if there is a problem.
Send a Net::RTP::Packet from out of the RTP socket. The PeerPort and PeerAddr should be defined in order to send packets. Returns the number of bytes sent, or the undefined value if there is an error.
Returns the name of the super-class that Net::RTP chose to use.
Please report any bugs or feature requests to
bug-net-rtp@rt.cpan.org, or through the web interface at
http://rt.cpan.org. I will be notified, and then you will automatically
be notified of progress on your bug as I make changes.
Nicholas J Humfrey, njh@cpan.org
Copyright (C) 2006 University of Southampton
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.005 or, at your option, any later version of Perl 5 you may have available.
| Net-RTP documentation | Contained in the Net-RTP distribution. |
package Net::RTP; ################ # # Net::RTP: Pure Perl Real-time Transport Protocol (RFC3550) # # Nicholas J Humfrey # njh@cpan.org # use Net::RTP::Packet; use Socket; use strict; use Carp; # Use whatever Superclass we can find first # we would prefer to have a multicast socket... BEGIN { my @superclasses = ( 'IO::Socket::Multicast6 0.02', 'IO::Socket::Multicast 1.00', 'IO::Socket::INET6 2.51', 'IO::Socket::INET 1.20', ); our $SUPER_CLASS = undef; foreach my $super (@superclasses) { eval "use $super"; unless ($@) { ($SUPER_CLASS) = ($super =~ /^([\w:]+)/); last; } } unless (defined $SUPER_CLASS) { die "Failed to load any of super classes."; } # Check to see if Socket6 is available our $HAVE_SOCKET6 = 0; eval "use Socket6 qw/ AF_INET6 unpack_sockaddr_in6 inet_ntop /;"; $HAVE_SOCKET6=1 unless ($@); } use vars qw/$VERSION @ISA $SUPER_CLASS $HAVE_SOCKET6/; @ISA = ($SUPER_CLASS); $VERSION="0.09"; sub new { my $class = shift; unshift @_,(Proto => 'udp') unless @_; return $class->SUPER::new(@_); } sub configure { my($self,$arg) = @_; # Default to UDP instead of TCP $arg->{Proto} ||= 'udp'; $arg->{ReuseAddr} ||= 1; my $result = $self->SUPER::configure($arg); if (defined $result) { # Join group if it a multicast IP address my $group = $self->sockhost(); if (_is_multicast_ip($group)) { if ($self->superclass() =~ /Multicast/) { #print "Joining group: $group\n"; $self->mcast_add( $group ) || croak "Failed to join multicast group"; } else { croak "Error: can't receive multicast without either ". "IO::Socket::Multicast or IO::Socket::Multicast6 installed."; } } } return $result; } sub _is_multicast_ip { my ($group) = @_; return 0 unless (defined $group); # IPv4 multicast address ? if ($group =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) { return 1 if ($1 >= 224 and $1 <= 239); # IPv6 multicast address ? } elsif ($group =~ /^ff[0-9a-f]{2}\:/i) { return 1; } # Not an multicast IP return 0; } sub superclass { return $SUPER_CLASS; } sub recv { my $self=shift; my ($size) = @_; # Default read size $size = 2048 unless (defined $size); # Receive a binary packet my $data = undef; my $sockaddr_in = $self->SUPER::recv($data, $size); if (defined $data and $data ne '') { # Parse the packet my $packet = new Net::RTP::Packet( $data ); # Store the source address if ($sockaddr_in ne '' and defined $packet) { if ($self->sockdomain() == &AF_INET) { my ($port,$addr) = unpack_sockaddr_in($sockaddr_in); $packet->{'source_ip'} = inet_ntoa($addr); $packet->{'source_port'} = $port; } elsif ($HAVE_SOCKET6) { eval { if ($self->sockdomain() == &AF_INET6) { my ($port,$addr) = unpack_sockaddr_in6($sockaddr_in); $packet->{'source_ip'} = inet_ntop(&AF_INET6, $addr); $packet->{'source_port'} = $port; } }; } # Failed to decode socket address ? unless (defined $packet->{'source_ip'}) { warn "Failed to get socket address for family: ".$self->sockdomain(); } } return $packet; } return undef; } sub send { my $self=shift; my ($packet) = @_; if (!defined $packet or ref($packet) ne 'Net::RTP::Packet') { croak "Net::RTP->send() takes a Net::RTP::Packet as its only argument"; } # Build packet and send it my $data = $packet->encode(); return $self->SUPER::send($data); } sub DESTROY { my $self=shift; return $self->SUPER::DESTROY(@_); } 1; __END__