Perl Cd Bookshelf [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Perl Cd Bookshelf [Electronic resources] - نسخه متنی

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید



17.4. Setting Up a UDP Client


17.4.1. Problem


You want to exchange messages with another
process using UDP (datagrams).

17.4.2. Solution


To set up a UDP socket handle, use either the low-level Socket module
on your own filehandle:

use Socket;
socket(SOCKET, PF_INET, SOCK_DGRAM, getprotobyname("udp"))
or die "socket: $!";

or else IO::Socket, which returns an anonymous
one:

use IO::Socket;
$handle = IO::Socket::INET->new(Proto => 'udp')
or die "socket: $@"; # yes, it uses $@ here

Then to send a message to a machine named
$HOSTNAME on port number
$PORTNO, use:

$ipaddr = inet_aton($HOSTNAME);
$portaddr = sockaddr_in($PORTNO, $ipaddr);
send(SOCKET, $MSG, 0, $portaddr) = = length($MSG)
or die "cannot send to $HOSTNAME($PORTNO): $!";

To receive a message of length no greater than
$MAXLEN, use:

$portaddr = recv(SOCKET, $MSG, $MAXLEN, 0) or die "recv: $!";
($portno, $ipaddr) = sockaddr_in($portaddr);
$host = gethostbyaddr($ipaddr, AF_INET);
print "$host($portno) said $MSG\n";

17.4.3. Discussion


Datagram
sockets are unlike stream sockets. Streams provide sessions, giving
the illusion of a stable connection. You might think of them as
working like a telephone call—expensive to set up, but once
established, reliable and easy to use. Datagrams, though, are more
like the postal system—it's cheaper and easier to send a letter
to your friend on the other side of the world than to call them on
the phone. Datagrams are easier on the system than streams. You send
a small amount of information one message at a time. But your
messages' delivery isn't guaranteed, and they might arrive in the
wrong order. Like a small post box, the receiver's queue might fill
up and cause further messages to be dropped.

Why then, if datagrams are unreliable, do we have them? Because some
applications are most sensibly implemented in terms of datagrams. For
instance, in streaming audio, it's more important that the stream as
a whole be preserved than that every packet get through, especially
if packets are being dropped because there's not enough bandwidth for
them all. Another use for datagrams is broadcasting, which
corresponds to mass mailing of advertisements in the postal model,
and is equally popular in most circles. One use for broadcast packets
is to send out a message to your local subnet saying, "Hey, is there
anybody around here who wants to be my server?"

Because datagrams don't provide the illusion of a lasting connection,
you get a little more freedom in how you use them. You don't have to
connect your socket to the remote end that you're
sending data. Instead, address each datagram individually when you
send. Assuming $remote_addr is
the result of a call to sockaddr_in, do this:

send(MYSOCKET, $msg_buffer, $flags, $remote_addr)
or die "Can't send: $!\n";

The only flag argument used much is MSG_OOB, which
lets you send and receive out-of-band data in advanced applications.

The remote
address should be a port and Internet address combination returned by
the Socket module's sockaddr_in function. If you
want, call connect on that address instead. Then
you can omit the last argument to your send s,
after which they'll all go to that recipient. Unlike streams, you are
free to reconnect to another machine with the same datagram socket.

Example 17-1 is a small example of a UDP program. It
contacts the UDP time port of the machine whose name is given on the
command line, or of the local machine by default. This doesn't work
on all machines, but those with a server will send you back a 4-byte
integer packed in network byte order representing the time that
machine thinks it is. The time returned, however, is in the number of
seconds since 1900. You have to subtract the number of seconds
between 1900 and 1970 to feed that time to the
localtime or gmtime conversion
functions.

Example 17-1. clockdrift


#!/usr/bin/perl
# clockdrift - compare another system's clock with this one
use strict;
use Socket;
my ($host, $him, $src, $port, $ipaddr, $ptime, $delta);
my $SECS_of_70_YEARS = 2_208_988_800;
socket(MsgBox, PF_INET, SOCK_DGRAM, getprotobyname("udp"))
or die "socket: $!";
$him = sockaddr_in(scalar(getservbyname("time", "udp")),
defined(send(MsgBox, 0, 0, $him))
or die "send: $!";
defined($src = $ptime, 4, 0))
or die "recv: $!";
($port, $ipaddr) = sockaddr_in($src);
$host = gethostbyaddr($ipaddr, AF_INET);
my $delta = (unpack("N", $ptime) - $SECS_of_70_YEARS) - time( );
print "Clock on $host is $delta seconds ahead of this one.\n";

If the machine you're trying to contact isn't alive or if its
response is lost, you'll only know because your program will get
stuck in the recv waiting for an answer that will
never come.

17.4.4. See Also


The send, recv,
gethostbyaddr, and unpack
functions in Chapter 29 of Programming Perl
and in perlfunc(1); the documentation for the
standard Socket and IO::Socket modules; the section on "Message
Passing" in Chapter 16 of Programming Perl and
in perlipc(1); UNIX Network
Programming
;
Recipe 17.5



17.3. Communicating over TCP17.5. Setting Up a UDP Server




Copyright © 2003 O'Reilly & Associates. All rights reserved.

/ 875