⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch12.htm

📁 《Perl 5 Unreleased》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
&nbsp;2<BR>

&nbsp;3 $addr = pack('C4',204,251,103,2);<BR>

&nbsp;4 ($name,$alias,$atype,$len,@addrs) = gethostbyaddr($addr,2);

<BR>

&nbsp;5 ($a,$b,$c,$d) = unpack('C4',$addrs[0]);<BR>

&nbsp;6 print &quot;Name :&nbsp;&nbsp;$name \n&quot;;<BR>

&nbsp;7 print &quot;Alias:&nbsp;&nbsp;$alias \n&quot;;<BR>

&nbsp;8 print &quot;Type :&nbsp;&nbsp;$atype \n&quot;;<BR>

&nbsp;9 print &quot;Len&nbsp;&nbsp;:&nbsp;&nbsp;$len \n&quot;;

<BR>

10 print &quot;Node :&nbsp;&nbsp;$a.$b.$c.$d \n&quot;;<BR>

11<BR>

12 $name = &quot;www.ikra.com&quot;;<BR>

13 ($name,$alias,$atype,$len,@addrs) = gethostbyname($name);<BR>

14 ($a,$b,$c,$d) = unpack('C4',$addrs[0]);<BR>

15 print &quot;Name :&nbsp;&nbsp;$name \n&quot;;<BR>

16 print &quot;Alias:&nbsp;&nbsp;$alias \n&quot;;<BR>

17 print &quot;Type :&nbsp;&nbsp;$atype \n&quot;;<BR>

18 print &quot;Len&nbsp;&nbsp;:&nbsp;&nbsp;$len \n&quot;;<BR>

19 print &quot;Node :&nbsp;&nbsp;$a.$b.$c.$d \n&quot;;</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,&nbsp;&nbsp;$AF_UNIX,

$STREAMS, $PROTOCOL) ||<BR>

&nbsp;&nbsp;&nbsp;&nbsp; die &quot;\nCannot open socket: $!\n&quot;;

<BR>

print &quot;\nSocket successfully opened\n&quot;;</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 &quot;$my_tst_srvr&quot; || die

&quot;\n$O: No permissions&quot;;</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,&quot;./mysocket&quot;)

|| die &quot;Cannot bind $!\n&quot;;</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;&nbsp;&nbsp;&nbsp;&nbsp; # 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 &quot;Cannot bind $!\n&quot;;</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&nbsp;&nbsp;&nbsp;&nbsp; address;<BR>

char nullbytes[8];<BR>

&nbsp;&nbsp;&nbsp;&nbsp; }</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 + -