📄 ch12.htm
字号:
2<BR>
3 $addr = pack('C4',204,251,103,2);<BR>
4 ($name,$alias,$atype,$len,@addrs) = gethostbyaddr($addr,2);
<BR>
5 ($a,$b,$c,$d) = unpack('C4',$addrs[0]);<BR>
6 print "Name : $name \n";<BR>
7 print "Alias: $alias \n";<BR>
8 print "Type : $atype \n";<BR>
9 print "Len : $len \n";
<BR>
10 print "Node : $a.$b.$c.$d \n";<BR>
11<BR>
12 $name = "www.ikra.com";<BR>
13 ($name,$alias,$atype,$len,@addrs) = gethostbyname($name);<BR>
14 ($a,$b,$c,$d) = unpack('C4',$addrs[0]);<BR>
15 print "Name : $name \n";<BR>
16 print "Alias: $alias \n";<BR>
17 print "Type : $atype \n";<BR>
18 print "Len : $len \n";<BR>
19 print "Node : $a.$b.$c.$d \n";</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR VALIGN=TOP><TD ><B>Note</B></TD></TR>
<TR VALIGN=TOP><TD >
<BLOCKQUOTE>
Note the use of the number <TT><FONT FACE="Courier">2</FONT></TT> in the call to <TT><FONT FACE="Courier">gethostbyaddr</FONT></TT> in Listing 12.3. This should be the constant <TT><FONT FACE="Courier">$AF_INET</FONT></TT>.
</BLOCKQUOTE>
</TD></TR>
</TABLE></CENTER>
<P>
<H2><A NAME="SocketPrimitives"><FONT SIZE=5 COLOR=#FF0000>Socket
Primitives</FONT></A></H2>
<P>
Enough already about getting information on your system. Let's
see what socket functions are available to you. Depending on your
site and what extensions you have for Perl, you may have more
functions available. Check the <TT><FONT FACE="Courier">man</FONT></TT>
pages for <TT><FONT FACE="Courier">socket</FONT></TT> for more
information. Here are the most common ones you'll use:
<UL>
<LI><TT><FONT FACE="Courier">socket()</FONT></TT>-Creates a socket
<LI><TT><FONT FACE="Courier">bind()</FONT></TT>-Binds a process
to a socket
<LI><TT><FONT FACE="Courier">accept()</FONT></TT>-Accepts an incoming
request for connection
<LI><TT><FONT FACE="Courier">listen()</FONT></TT>-Use for servers
to begin listening for connections to a <TT><FONT FACE="Courier">socket</FONT></TT>
<LI><TT><FONT FACE="Courier">connect()</FONT></TT>-Use for clients
to connect to a server
<LI><TT><FONT FACE="Courier">read()</FONT></TT>-Reads binary data
from a socket
<LI><TT><FONT FACE="Courier">write()</FONT></TT>-Writes binary
data to a socket
</UL>
<P>
I cover these functions in the following sections. However, there
are some constants that must be defined before I continue. These
constants are used in all function calls and scripts in this chapter.
Feel free to change them to reflect your own system's peculiarities.
Here's a list of the constants:
<UL>
<LI><TT><FONT FACE="Courier">$AF_UNIX = 1</FONT></TT>. You'll
be working with the <TT><FONT FACE="Courier">AF_UNIX</FONT></TT>
family of protocols.
<LI><TT><FONT FACE="Courier">$SOCK_STR = 1</FONT></TT>. When you
work with UDP, set this variable to <TT><FONT FACE="Courier">2</FONT></TT>.
If you will work with TCP/IP only, set it to <TT><FONT FACE="Courier">1</FONT></TT>.
<LI><TT><FONT FACE="Courier">$PROTOCOL = 0</FONT></TT>. The default
protocol for all our examples is the one you will most probably
wind up using anyway-IP. See <TT><FONT FACE="Courier">man</FONT></TT>
pages for protocols for more information about what other types
are available.
</UL>
<H3><A NAME="socket"><TT><FONT SIZE=4 FACE="Courier">socket()</FONT></TT></A>
</H3>
<P>
The <TT><FONT FACE="Courier">socket()</FONT></TT> system call
creates a socket for the client or the server. The socket function
is defined as this:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">socket(SOCKET_HANDLE, $FAMILY, $TYPE,
$PROTOCOL);</FONT></TT>
</BLOCKQUOTE>
<P>
The return value from this function is <TT><FONT FACE="Courier">NULL</FONT></TT>,
and if there was an error, you should check the <TT><FONT FACE="Courier">$!</FONT></TT>
for the type of error message. The call to open a socket looks
like this:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">socket(MY_HANDLE, $AF_UNIX,
$STREAMS, $PROTOCOL) ||<BR>
die "\nCannot open socket: $!\n";
<BR>
print "\nSocket successfully opened\n";</FONT></TT>
</BLOCKQUOTE>
<P>
It's a good idea to unlink any existing file names for previously
opened sockets with the <TT><FONT FACE="Courier">unlink</FONT></TT>
call:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">unlink "$my_tst_srvr" || die
"\n$O: No permissions";</FONT></TT>
</BLOCKQUOTE>
<P>
You'll use the socket descriptor <TT><FONT FACE="Courier">MY_HANDLE</FONT></TT>
to refer to this socket in all subsequent network function calls
in your program. Sockets are created without a name. Clients use
the name of the socket in order to read or write to it. This is
where the <TT><FONT FACE="Courier">bind</FONT></TT> function comes
in.
<H3><A NAME="ThebindSystemCall">The <TT><FONT SIZE=4 FACE="Courier">bind()</FONT></TT><FONT SIZE=4>
System Call</FONT></A></H3>
<P>
The <TT><FONT FACE="Courier">bind()</FONT></TT> system call assigns
a name to an unnamed socket:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">bind(SOCKET_HANDLE, $nameAsAString);
<BR>
bind(SOCKET_HANDLE, $sockaddr);</FONT></TT>
</BLOCKQUOTE>
<P>
The first item is the socket descriptor you just created. The
second parameter is the name that refers to this socket if you
are using <TT><FONT FACE="Courier">AF_UNIX</FONT></TT> or its
address if you are using <TT><FONT FACE="Courier">AF_INET</FONT></TT>.
<P>
The call to bind using <TT><FONT FACE="Courier">AF_UNIX</FONT></TT>
looks like this:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">bind(MY_HANDLE,"./mysocket")
|| die "Cannot bind $!\n";</FONT></TT>
</BLOCKQUOTE>
<P>
In <TT><FONT FACE="Courier">AF_INET</FONT></TT>, it looks like
this:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">$port = 6666<BR>
$AF_INET=2; # Use AF_INET instead of AF_UNIX
<BR>
($name,$alias,$atype,$len,$addr)=gethostbyname(`uname -n`);<BR>
$my_ip_addr = pack(S n C4 x8,$AF_INET,$STREAMS,$port,$addr);<BR>
bind(MY_HANDLE,$my_ip_addr) || die "Cannot bind $!\n";</FONT></TT>
</BLOCKQUOTE>
<P>
The parameters' <TT><FONT FACE="Courier">pack()</FONT></TT> function
probably needs some explanation. The <TT><FONT FACE="Courier">pack()</FONT></TT>
function takes two parameters: a list of formats to use and a
list of values to pack into one continuous stream of bytes. In
our case, the <TT><FONT FACE="Courier">bind()</FONT></TT> call
expects a <TT><FONT FACE="Courier">sockaddr</FONT></TT> structure
of the following form in a C structure:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">{<BR>
unsigned short family;<BR>
int network;<BR>
long address;<BR>
char nullbytes[8];<BR>
}</FONT></TT>
</BLOCKQUOTE>
<P>
The first parameter to the <TT><FONT FACE="Courier">pack</FONT></TT>
instruction can take the values listed in Table 12.1. Check the
<TT><FONT FACE="Courier">man</FONT></TT> pages for the <TT><FONT FACE="Courier">pack</FONT></TT>
instruction for more details. You had the <TT><FONT FACE="Courier">pack</FONT></TT>
instruction create the socket address structure for you. Therefore,
the script uses <TT><FONT FACE="Courier">S n C4 x8</FONT></TT>
to pack a signed <TT><FONT FACE="Courier">short</FONT></TT>, followed
by an integer in network order, four unsigned characters, and
eight <TT><FONT FACE="Courier">NULL</FONT></TT> characters to
get this call:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">pack(S n C4 x8,$AF_INET,$STREAMS,$port,$addr);
<BR>
</FONT></TT>
</BLOCKQUOTE>
<P>
<CENTER><B>Table 12.1. The types of packing supported by </B><TT><B><FONT FACE="Courier">pack()</FONT></B></TT><B>.</
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -