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

📄 ch18.htm

📁 prrl 5 programs codes in the book
💻 HTM
📖 第 1 页 / 共 5 页
字号:


</TD></TR>

</TABLE>

</CENTER>

<P>

<P>

The second line of this short example creates a full Internet

socket address using the <TT>pack()</TT>

fuNCtion. This is another complicated topic that I will sidestep.

As long as you know the port number and the server's address,

you can simply plug those values into the example code and not

worry about the rest. The important part of the example is the

&quot;\0\0\0\0&quot; string. This string holds the four numbers

that make up the dotted decimal Internet address. If you already

know the dotted decimal address, convert each number to octal

and replace the appropriate \0 in the string.

<P>

If you know the symbolic name of the server instead of the dotted

decimal address, use the following line to create the packed Internet

address:

<BLOCKQUOTE>

<PRE>

$internetPackedAddress = pack('S n A4 x8', AF_INET(), $port, 

    gethostbyname('www.remotehost.com'));

</PRE>

</BLOCKQUOTE>

<P>

After the socket has been created and an address has been bound

to it, you need to create a queue for the socket. This is done

with the <TT>listen()</TT> fuNCtion.

The <TT>listen()</TT> call looks like

this:

<BLOCKQUOTE>

<PRE>

listen(SOCKET, 5) or die(&quot;listen: $!&quot;);

</PRE>

</BLOCKQUOTE>

<P>

This <TT>listen()</TT> statement will

create a queue that can handle 5 remote attempts to connect. The

sixth attempt will fail with an appropriate error code.

<P>

Now that the socket exists, has an address, and has a queue, your

program is ready to begin a conversation using the <TT>accept()</TT>

fuNCtion. The <TT>accept()</TT> fuNCtion

makes a copy of the socket and starts a conversation with the

new socket. The original socket is still available and able to

accept connections. You can use the <TT>fork()</TT>

fuNCtion, in UNIX, to create child processes to handle multiple

conversations. The normal <TT>accept()</TT>

fuNCtion call looks like this:

<BLOCKQUOTE>

<PRE>

$addr = accept(NEWSOCKET, SOCKET) or die(&quot;accept: $!&quot;);

</PRE>

</BLOCKQUOTE>

<P>

Now that the conversation has been started, use <TT>print()</TT>,

<TT>send()</TT>, <TT>recv()</TT>,

<TT>read()</TT>, or <TT>write()</TT>

to hold the conversation. The examples later in the chapter show

how the conversations are held.

<H3><A NAME="TheClientSideofaConversation">

The Client Side of a Conversation</A></H3>

<P>

Client programs will use <TT>socket()</TT>

to create a socket and <TT>connect()</TT>

to initiate a connection to a server's socket. Then input/output

fuNCtions are used to hold  a conversation. And the <TT>close()</TT>

fuNCtion closes the socket.

<P>

The <TT>socket()</TT> call for the

client program is the same as that used in the server:

<BLOCKQUOTE>

<PRE>

$tcpProtocolNumber = getprotobyname('tcp') || 6;



socket(SOCKET, PF_INET(), SOCK_STREAM(), $tcpProtocolNumber)

    or die(&quot;socket: $!&quot;);

</PRE>

</BLOCKQUOTE>

<P>

After the socket is created, the <TT>connect()</TT>

fuNCtion is called like this:

<BLOCKQUOTE>

<PRE>

$port = 20001;

$internetPackedAddress = pack('Sna4x8', AF_INET(), $port, &quot;\0\0\0\0&quot;);



connect(SOCKET, $internetPackedAddress) or die(&quot;connect: $!&quot;);

</PRE>

</BLOCKQUOTE>

<P>

The packed address was explained in &quot;The Server Side of a

Conversation.&quot; The <TT>SOCKET</TT>

parameter has no relation to the name used on the server machine.

I use <TT>SOCKET</TT> on both sides

for convenieNCe.

<P>

The <TT>connect()</TT> fuNCtion is

a <I>blocking</I> fuNCtion. This means that it will wait until

the connection is completed. You can use the <TT>select()</TT>

fuNCtion to set non-blocking mode, but you'll need to look in

the UNIX documentation to find out how. It's a bit complicated

to explain here.

<P>

After the connection is made, you use the normal input/output

fuNCtions or the <TT>send()</TT> and

<TT>recv()</TT> fuNCtions to talk

with the server.

<P>

The rest of the chapter will be devoted to looking at examples

of specific protocols. Let's start out by looking at the time

service.

<H2><A NAME="UsingtheTimeService"><FONT SIZE=5 COLOR=#FF0000>

Using the Time Service</FONT></A></H2>

<P>

It is very important that all computers on a given network report

the same time. This allows backups and other regularly scheduled

events to be automated. Instead of manually adjusting the time

on every computer in the network, you can designate a time server.

The other computers can use the time server to determine the correct

time and adjust their own clocks accordingly.

<P>

Listing 18.1 contains a program that can retrieve the time from

any time server in the world. Modify the example to access your

own time server by setting the <TT>$remoteServer</TT>

variable to your server's symbolic name.

<P>

<IMG SRC="pseudo.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/pseudo.gif" BORDER=1 ALIGN=RIGHT><p>

<BLOCKQUOTE>

<I>Turn on the warning compiler option.<BR>

Load the </I><TT><I>Socket</I></TT><I>

module.<BR>

Turn on the strict pragma.<BR>

Initialize the </I><TT><I>$remoteServer</I></TT><I>

to the symbolic name of the time server.<BR>

Set a variable equal to the number of seconds in 70 years.<BR>

Initialize a buffer variable, </I><TT><I>$buffer</I></TT><I>.

<BR>

Declare </I><TT><I>$socketStructure</I></TT><I>.

<BR>

Declare </I><TT><I>$serverTime</I></TT><I>.

<BR>

Get the tcp protocol and time port numbers, provide a default

in case the </I><TT><I>getprotobyname()</I></TT><I>

and </I><TT><I>getservbyname()</I></TT><I>

fuNCtions are notimplemented.<BR>

Initialize </I><TT><I>$serverAddr</I></TT><I>

with the Internet address of the time server.<BR>

Display the current time on the local machine, also called the

localhost.<BR>

Create a socket using the standard parameters.<BR>

Initialize </I><TT><I>$packedFormat</I></TT><I>

with format specifiers.<BR>

Connect the local socket to the remote socket that is providing

the time service.<BR>

Read the server's time as a 4 byte value. <BR>

Close the local socket.<BR>

Unpack the network address from a long (4 byte) value into a string

value.<BR>

Adjust the server time by the number of seconds in 70 years.<BR>

Display the server's name, the number of seconds differeNCe between

the remote time and the local time.<BR>

Declare the </I><TT><I>ctime()</I></TT><I>

fuNCtion.<BR>

Return a string reflecting the time represented by the parameter.</I>

</BLOCKQUOTE>

<HR>

<BLOCKQUOTE>

<B>Listing 18.1&nbsp;&nbsp;18LST01.PL-Getting the Time from a

Time Service<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

#!/usr/bin/perl  -w



use Socket;

use strict;



my($remoteServer)     = 'saturn.planet.net';



my($secsIn70years)    = 2208988800;

my($buffer)           = '';

my($socketStructure);

my($serverTime);



my($proto)      = getprotobyname('tcp')        || 6;

my($port)       = getservbyname('time', 'tcp') || 37;



my($serverAddr) = (gethostbyname($remoteServer))[4];



printf(&quot;%-20s %8s %s\n&quot;,  &quot;localhost&quot;, 0, ctime(time()));



socket(SOCKET, PF_INET, SOCK_STREAM, $proto)

    or die(&quot;socket: $!&quot;);



my($packFormat) = 'S n a4 x8';   # Windows 95, SunOs 4.1+

#my($packFormat) = 'S n c4 x8';   # SunOs 5.4+ (Solaris 2)

connect(SOCKET, pack($packFormat, AF_INET(), $port, $serverAddr))

    or die(&quot;connect: $!&quot;);



read(SOCKET, $buffer, 4);

close(SOCKET);



$serverTime  = unpack(&quot;N&quot;, $buffer);

$serverTime -= $secsIn70years;



printf(&quot;%-20s %8d %s\n&quot;, $remoteServer, $serverTime - time,

    ctime($serverTime));



sub ctime {

    return(scalar(localtime($_[0])));

}

</PRE>

</BLOCKQUOTE>

<HR>

<P>

Each operating system will have a different method to update the

local time. So I'll leave it in your hands to figure how to do

that.

<P>

The next section is devoted to sending mail. First the protocol

will be explained and then you will see a Perl script that can

send a mail message.

<H2><A NAME="SendingMailSMTP"><FONT SIZE=5 COLOR=#FF0000>

Sending Mail (SMTP)</FONT></A></H2>

<P>

Before you send mail, the entire message needs to be composed.

You need to know where it is going, who gets it, and what the

text of the message is. When this information has been gathered,

you begin the process of transferring the information to a mail

server.<BR>

<p>

<CENTER>

<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>

<TR><TD><B>Note</B></TD></TR>

<TR><TD>

<BLOCKQUOTE>

The mail service will be listening for your connection on TCP port 25. But this information will not be important until you see some Perl code later in the chapter.</BLOCKQUOTE>



</TD></TR>

</TABLE>

</CENTER>

<P>

<P>

The message that you prepare can only use alphanumeric characters.

If you need to send binary information (like files), use the MIME

protocol. The details of the MIME protocol can be found at the

<B>http://ds.internic.net/ds/dspg0intdoc.html</B> Web site.

<P>

SMTP uses several commands to communicate with mail servers. These

commands are described in Table 18.3. The commands are not case-insensitive,

which means you can use either Mail or MAIL. However, remember

that mail addresses are case-sensitive.<BR>

<CENTER><B>Table 18.3&nbsp;&nbsp;The SMTP Command Set</B></CENTER>

<p>

<CENTER>

<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>

<TR><TD WIDTH=133><CENTER><I>Command</I></CENTER></TD><TD WIDTH=457><I>Description</I>

</TD></TR>

<TR><TD COLSPAN=2 WIDTH=590><B>Basic Commands</B></TD></TR>

<TR><TD WIDTH=133><CENTER><TT>HELO</TT></CENTER>

</TD><TD WIDTH=457>Initiates a conversation with the mail server. When using this command you can specify your domain name so that the mail server knows who you are. For example, <TT>HELO mailhost2. planet.net</TT>.

</TD></TR>

<TR><TD WIDTH=133><CENTER><TT>MAIL</TT></CENTER>

</TD><TD WIDTH=457>Indicates who is sending the mail. For example, <TT>MAIL FROM: &lt;medined@planet.net&gt;</TT>. Remember this is not <I>your</I> name, it's the name of the person who is sending the mail message. Any returned mail will be sent back to 
this address.

</TD></TR>

<TR><TD WIDTH=133><CENTER><TT>RCPT</TT></CENTER>

</TD><TD WIDTH=457>Indicates who is recieving the mail. For example, <TT>RCPT TO: &lt;rolf@earthdawn.com&gt;</TT>. You can indicate more than one user by issuing multiple <TT>RCPT</TT> commands.

</TD></TR>

<TR><TD WIDTH=133><CENTER><TT>DATA</TT></CENTER>

</TD><TD WIDTH=457>Indicates that you are about to send the text (or body) of the message. The message text must end with the following five letter sequeNCe: &quot;\r\n.\r\n.&quot;

</TD></TR>

<TR><TD WIDTH=133><CENTER><TT>QUIT</TT></CENTER>

</TD><TD WIDTH=457>Indicates that the conversation is over.</TD>

</TR>

<TR><TD COLSPAN=2 WIDTH=590><B>AdvaNCed Commands (see RFC 821 for details)</B>

</TD></TR>

<TR><TD WIDTH=133><CENTER><TT>EXPN</TT></CENTER>

</TD><TD WIDTH=457>Indicates that you are using a mailing list.

</TD></TR>

<TR><TD WIDTH=133><CENTER><TT>HELP</TT></CENTER>

</TD><TD WIDTH=457>Asks for help from the mail server.</TD></TR>

<TR><TD WIDTH=133><CENTER><TT>NOOP</TT></CENTER>

</TD><TD WIDTH=457>Does nothing other than get a reponse from the mail server.

</TD></TR>

<TR><TD WIDTH=133><CENTER><TT>RSET</TT></CENTER>

</TD><TD WIDTH=457>Aborts the current conversation.</TD></TR>

<TR><TD WIDTH=133><CENTER><TT>SEND</TT></CENTER>

</TD><TD WIDTH=457>Sends a message to a user's terminal instead of a mailbox.

</TD></TR>

<TR><TD WIDTH=133><CENTER><TT>SAML</TT></CENTER>

</TD><TD WIDTH=457>Sends a message to a user's terminal and to a user's mailbox.

</TD></TR>

<TR><TD WIDTH=133><CENTER><TT>SOML</TT></CENTER>

</TD><TD WIDTH=457>Sends a message to a user's terminal if they are logged on; otherwise, sends the message to the user's mailbox.

</TD></TR>

<TR><TD WIDTH=133><CENTER><TT>TURN</TT></CENTER>

</TD><TD WIDTH=457>Reverses the role of client and server. This might be useful if the client program can also act as a server and needs to receive mail from the remote computer.

</TD></TR>

<TR><TD WIDTH=133><CENTER><TT>VRFY</TT></CENTER>

</TD><TD WIDTH=457>Verifies the existeNCe and user name of a given mail address. This command is not implemented in all mail servers. And it can be blocked by firewalls.

</TD></TR>

</TABLE>

</CENTER>

<P>

<P>

Every command will receive a reply from the mail server in the

form of a three digit number followed by some text describing

the reply. For example, <TT>250 OK</TT>

or <TT>500 Syntax error, command unrecognized</TT>.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -