_chapter 3.htm
来自「Core Java 2(中文名称:JAVA 2 核心技术 卷二:高级特性)这是英」· HTM 代码 · 共 1,237 行 · 第 1/4 页
HTM
1,237 行
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Chapter 3</title>
<link rel="stylesheet" type="text/css" href="docsafari.css">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<ul></ul>
<table width="100%" border="1" bgcolor="#EBEBFF">
<tr>
<td width="5%" align="left" valign="middle"><a href="_chapter%202.htm"><img src="Larrow.gif" width="17" height="19" border="0"></a></td>
<td align="center" valign="middle"><a class="docLink" href="Front%20matter.htm">CONTENTS</a></td>
<td width="5%" align="right" valign="middle"><a href="_chapter%204.htm"><img src="Rarrow.gif" width="17" height="19" border="0"></a></td>
</tr>
</table>
<h2 class="docChapterTitle">Chapter 3. Networking</h2>
<ul>
<li>
<p class="docList"><a class="docLink" href="#c3s1">Connecting to a Server</a></li>
<li>
<p class="docList"><a class="docLink" href="#c3s2">Implementing Servers</a></li>
<li>
<p class="docList"><a class="docLink" href="#c3s3">Sending E-Mail</a></li>
<li>
<p class="docList"><a class="docLink" href="#c3s4">Advanced Socket Programming</a></li>
<li>
<p class="docList"><a class="docLink" href="#c3s5">URL Connections</a></li>
<li>
<p class="docList"><a class="docLink" href="#c3s6">Posting Form Data</a></li>
<li>
<p class="docList"><a class="docLink" href="#c3s7">Harvesting Information from the Web</a></li>
</ul>
<p class="docText">The Java programming language is supposed to become the
premier tool for connecting computers over the Internet and corporate intranets
and, in this realm, Java mostly lives up to the hype. If you are accustomed to
programming network connections in C or C++, you will be pleasantly surprised at
how easy it is to program them in the Java programming language. For example, as
you saw in the applet chapter in Volume 1, it is easy to open a URL (uniform
resource locator) on the Net: simply pass the URL to the <tt>showDocument</tt>
method in the <tt>AppletContext</tt> class.</p>
<p class="docText">We begin this chapter by talking a little bit about basic
networking. Then, we move on to reviewing and extending the information that was
briefly presented in the applet chapter in Volume 1. The rest of the chapter
moves on to the intricacies of doing sophisticated work on the Net with the Java
programming language. For example, we give you a glimpse into server-side
programming with Java. In particular, we show you how to use a combination of an
applet and a servlet to harvest information on the Internet.</p>
<p class="docText">In the first part of this chapter, we assume that you have no
network programming experience. If you have written TCP/IP programs before and
ports and sockets are no mystery to you, you should breeze through the sample
code. Toward the end of this chapter, the code becomes complex and is geared
more toward those with some experience in network programming.</p>
<h3 class="docSection1Title" id="c3s1">Connecting to a Server</h3>
<p class="docText">Before writing our first network program, let's learn about a
great debugging tool for network programming that you already have, namely,
telnet. Most systems (both UNIX and Windows) always come with telnet. However,
it is optional with some installations, and you may not have requested it when
you installed the operating system. If you can't run telnet from a command
shell, then you need to add it from your operating system installation disk.</p>
<p class="docText">You may have used telnet to connect to a remote computer and
to check your e-mail, but you can use it to communicate with other services
provided by Internet hosts as well. Here is an example of what you can do. Type</p>
<pre>telnet time-A.timefreq.bldrdoc.gov 13
</pre>
<p class="docText">As <a class="docLink" href="#ch03fig01">Figure 3-1</a> shows,
you should get back a line like this:</p>
<center>
<h5 id="ch03fig01" class="docFigureTitle">Figure 3-1. Output of the "time of day" service</h5>
<p>
<img alt="graphics/03fig01.gif" src="03fig01.gif" border="0" width="500" height="278"></p>
</center>
<pre>52088 01-06-28 14:35:13 50 0 0 644.8 UTC(NIST) *
</pre>
<p class="docText">What is going on? You have connected to the "time of day"
service that most UNIX machines constantly run. The particular server that you
connected to is operated by the National Institute of Standards and Technology
in Boulder, Colorado, and gives the measurement of a Cesium atomic clock. (Of
course, the reported time is not completely accurate due to network delays.) By
convention, the "time of day" service is always attached to "port" number 13.</p>
<div class="docNote">
<p class="docNoteTitle">NOTE</p>
<table cellSpacing="0" cellPadding="1" width="90%" border="0">
<tr>
<td vAlign="top" width="60">
<img alt="graphics/note.gif" src="note.gif" align="left" border="0" width="54" height="53"><br>
</td>
<td vAlign="top">
<p class="docText">In network parlance, a port is not a physical device,
but an abstraction to facilitate communication between a server and a
client (see <a class="docLink" href="#ch03fig02">Figure 3-2</a>).</p>
<center>
<h5 id="ch03fig02" class="docFigureTitle">Figure 3-2. A client connecting to a server
port</h5>
<p>
<img alt="graphics/03fig02.gif" src="03fig02.gif" border="0" width="500" height="193"><br>
</p>
</center></td>
</tr>
</table>
</div>
<p class="docText">What is happening is that the server software is continuously
running on the remote machine, waiting for any network traffic that wants to
chat with port 13. When the operating system on the remote computer gets a
network package that contains a request to connect to port number 13, it wakes
up the listening server process and establishes the connection. The connection
stays up until it is terminated by one of the parties.</p>
<p class="docText">When you began the telnet session with <tt>time-A.timefreq.bldrdoc.gov</tt>
at port 13, an unrelated piece of network software knew enough to convert the
string <tt>"time-A.timefreq.bldrdoc.gov"</tt> to its correct Internet Protocol
address, 132.163.4.102. The software then sent a connection request to that
computer, asking for a connection to port 13. Once the connection was
established, the remote program sent back a line of data and then closed the
connection. In general, of course, clients and servers engage in a more
extensive dialog before one or the other closes the connection.</p>
<p class="docText">Here is another experiment, along the same lines, that is a
bit more interesting. Do the following:</p>
<ol class="docList">
<li value="1">
<p class="docList">On Windows, turn on the local key echo in the Terminal
Preferences dialog box.</li>
<li value="2">
<p class="docList">Connect to
<a class="docLink" href="http://java.sun.com" target="_blank">java.sun.com</a>
on port 80.</li>
<li value="3">
<p class="docList">Type the following, <span class="docEmphasis">exactly as it
appears, without pressing backspace</span>.</li>
<li value="4">
<p class="docList"><tt>GET / HTTP/1.0</tt></li>
<li value="5">
<p class="docList">Now, press the ENTER key <span class="docEmphasis">two
times</span>.</li>
</ol>
<p class="docText"><a class="docLink" href="#ch03fig03">Figure 3-3</a> shows the
response. It should look eerily familiar梱ou got a page of HTML-formatted text,
namely, the main web page for Java technology.</p>
<center>
<h5 id="ch03fig03" class="docFigureTitle">Figure 3-3. Using telnet to access an HTTP port</h5>
<p>
<img alt="graphics/03fig03.gif" src="03fig03.gif" border="0" width="500" height="278"></p>
</center>
<p class="docText">This is <span class="docEmphasis">exactly</span> the same
process that your web browser goes through to get a web page.</p>
<p class="docText">Our first network program in
<a class="docLink" href="#ch03list01">Example 3-1</a> will do the same thing we
did using telnet梒onnect to a port and print out what it finds.</p>
<h5 id="ch03list01" class="docExampleTitle">Example 3-1 SocketTest.java</h5>
<pre> 1. import java.io.*;
2. import java.net.*;
3.
4. /**
5. This program makes a socket connection to the atomic clock
6. in Boulder, Colorado, and prints the time that the
7. server sends.
8. */
9. public class SocketTest
10. {
11. public static void main(String[] args)
12. {
13. try
14. {
15. Socket s = new Socket("time-A.timefreq.bldrdoc.gov",
16. 13);
17.
18. BufferedReader in = new BufferedReader
19. (new InputStreamReader(s.getInputStream()));
20. boolean more = true;
21. while (more)
22. {
23. String line = in.readLine();
24. if (line == null)
25. more = false;
26. else
27. System.out.println(line);
28. }
29.
30. }
31. catch (IOException e)
32. {
33. e.printStackTrace();
34. }
35. }
36. }
</pre>
<p class="docText">This program is extremely simple, but before we analyze the
two key lines, note that we are importing the <tt>java.net</tt> package and
catching any input/output errors because the code is encased in a <tt>try/catch</tt>
block. (Since many things can go wrong with a network connection, most of the
network-related methods threaten to throw I/O errors. You must catch them for
the code to compile.)</p>
<p class="docText">As for the code itself, the key lines are as follows:</p>
<pre>Socket s = new Socket("time-A.timefreq.bldrdoc.gov", 13);
BufferedReader in = new BufferedReader
(new InputStreamReader(s.getInputStream()));
</pre>
<p class="docText">The first line opens a <span class="docEmphasis">socket,</span>
which is an abstraction for the network software that enables communication out
of and into this program. We pass the remote address and the port number to the
socket constructor. If the connection fails, then an <tt>UnknownHostException</tt>
is thrown. If there is another problem, then an <tt>IOException</tt> occurs.
Since <tt>UnknownHostException</tt> is a subclass of <tt>IOException</tt> and
this is a sample program, we just catch the superclass.</p>
<p class="docText">Once the socket is open, the <tt>getInputStream</tt> method
in<tt>java.net.Socket</tt> returns an <tt>InputStream</tt> object that you can
use just like any other stream. (See Chapter 12 of Volume 1.) Once you have
grabbed the stream, this program simply</p>
<ol class="docList">
<span style="font-weight: bold" TYPE="1">
<li><span style="font-weight: normal">
<p class="docList">Reads all characters sent by the server using <tt>readLine;</tt></span></li>
<li><span style="font-weight: normal">
<p class="docList">Prints each line out to standard output.</span></span></li>
</ol>
<p class="docText">This process continues until the stream is finished and the
server disconnects. You know this happens when the <tt>readLine</tt> method
returns a <tt>null</tt> string.</p>
<div class="docNote">
<p class="docNoteTitle">NOTE</p>
<table cellSpacing="0" cellPadding="1" width="90%" border="0">
<tr>
<td vAlign="top" width="60">
<img alt="graphics/note.gif" src="note.gif" align="left" border="0" width="54" height="53"><br>
</td>
<td vAlign="top">
<p class="docText">This program works only with very simple servers, such
as a "time of day" service. In more complex networking programs, the
client sends request data to the server, and the server may not
immediately disconnect at the end of a response. You will see how to
implement that behavior in several examples throughout this chapter.</td>
</tr>
</table>
</div>
<p class="docText">Plainly, the <tt>Socket</tt> class is pleasant and easy to
use because Java technology hides the complexities of establishing a networking
connection and sending data across. The <tt>java.net</tt> package essentially
gives you the same programming interface you would use to work with a file.</p>
<h3 class="docSection1Title" id="c3s2">Implementing Servers</h3>
<p class="docText">Now that we have implemented a basic network client that
receives data from the Net, let's implement a simple server that can send
information out to the Net. Once you start the server program, it waits for some
client to attach to its port. We chose port number 8189, which is not used by
any of the standard services. The <tt>ServerSocket</tt> class is used to
establish a socket. In our case, the command</p>
<pre>ServerSocket s = new ServerSocket(8189);
</pre>
<p class="docText">establishes a server that monitors port 8189. The command</p>
<pre>Socket incoming = s.accept();
</pre>
<p class="docText">tells the program to wait indefinitely until a client
connects to that port. Once someone connects to this port by sending the correct
request over the network, this method returns a <tt>Socket</tt> object that
represents the connection that was made. You can use this object to get an input
reader and an output writer from that socket, as is shown in the following code:</p>
<pre>BufferedReader in = new BufferedReader
(new InputStreamReader(incoming.getInputStream()));
PrintWriter out = new PrintWriter
(incoming.getOutputStream(), true /* autoFlush */);
</pre>
<p class="docText">Everything that the server sends to the server output stream
becomes the input of the client program, and all the output from the client
program ends up in the server input stream.</p>
<p class="docText">In all of the examples in this chapter, we will transmit text
through sockets. We, therefore, turn the streams into readers and writers. Then,
we can use the <tt>readLine</tt> method (defined in <tt>BufferedReader</tt>, but
not in <tt>InputStream</tt>) and the <tt>print</tt> method (defined in <tt>
PrintWriter</tt>, but not in <tt>OutputStream</tt>). If we wanted to transmit
<span class="docEmphasis">binary data,</span> we would turn the streams into <tt>
DataInputStream</tt> and <tt>DataOutputStreams</tt>. To transmit
<span class="docEmphasis">serialized objects,</span> we would use <tt>
ObjectInputStream</tt> and <tt>ObjectOutputStreams</tt> instead.</p>
<p class="docText">Let's send the client a greeting:</p>
<pre>out.println("Hello! Enter BYE to exit.");
</pre>
<p class="docText">When you use telnet to connect to this server program at port
8189, you will see the above greeting on the terminal screen.</p>
<p class="docText">In this simple server, we just read the client input, a line
at a time, and echo it. This demonstrates that the program gets the client's
input. An actual server would obviously compute and return an answer that
depended on the input.</p>
<pre>String line = in.readLine();
if (line != null)
{
out.println("Echo: " + line);
if (line.trim().equals("BYE")) done = true;
}
else done = true;
</pre>
<p class="docText">In the end, we close the incoming socket.</p>
<pre>incoming.close();
</pre>
<p class="docText">That is all there is to it. Every server program, such as an
HTTP web server, continues performing this loop:</p>
<ol class="docList">
<span style="font-weight: bold" TYPE="1">
<li><span style="font-weight: normal">
<p class="docList">It gets a command from the client ("get me this
information") through an incoming data stream.</span></li>
<li><span style="font-weight: normal">
<p class="docList">It somehow fetches the information.</span></li>
<li><span style="font-weight: normal">
<p class="docList">It sends the information to the client through the outgoing
data stream.</span></span></li>
</ol>
<p class="docText"><a class="docLink" href="#ch03list02">Example 3-2</a> is the
complete program.</p>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?