_chapter 3.htm
来自「Core Java 2(中文名称:JAVA 2 核心技术 卷二:高级特性)这是英」· HTM 代码 · 共 1,237 行 · 第 1/4 页
HTM
1,237 行
<h5 id="ch03list02" class="docExampleTitle">Example 3-2 EchoServer.java</h5>
<pre> 1. import java.io.*;
2. import java.net.*;
3.
4. /**
5. This program implements a simple server that listens to
6. port 8189 and echoes back all client input.
7. */
8. public class EchoServer
9. {
10. public static void main(String[] args )
11. {
12. try
13. {
14. // establish server socket
15. ServerSocket s = new ServerSocket(8189);
16.
17. // wait for client connection
18. Socket incoming = s.accept( );
19. BufferedReader in = new BufferedReader
20. (new InputStreamReader(incoming.getInputStream()));
21. PrintWriter out = new PrintWriter
22. (incoming.getOutputStream(), true /* autoFlush */);
23.
24. out.println( "Hello! Enter BYE to exit." );
25.
26. // echo client input
27. boolean done = false;
28. while (!done)
29. {
30. String line = in.readLine();
31. if (line == null) done = true;
32. else
33. {
34. out.println("Echo: " + line);
35.
36. if (line.trim().equals("BYE"))
37. done = true;
38. }
39. }
40. incoming.close();
41. }
42. catch (Exception e)
43. {
44. e.printStackTrace();
45. }
46. }
47. }
</pre>
<p class="docText">To try it out, you need to compile and run the program. Then,
use telnet to connect to the following server and port:</p>
<blockquote>
<p class="docList">Server: 127.0.0.1</p>
<p class="docList">Port: 8189</p>
</blockquote>
<p class="docText">The IP address 127.0.0.1 is a special address, called the
<span class="docEmphasis">local loopback address,</span> that denotes the local
machine. Since you are running the echo server locally, that is where you want
to connect.</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">If you are using a dial-up connection, you need to have
it running for this experiment. Even though you are only talking to your
local machine, the network software must be loaded.</td>
</tr>
</table>
</div>
<p class="docText">Actually, anyone in the world can access your echo server,
provided it is running and they know your IP address and the magic port number.</p>
<p class="docText">When you connect to the port, you will get the message shown
in <a class="docLink" href="#ch03fig04">Figure 3-4</a>:</p>
<center>
<h5 id="ch03fig04" class="docFigureTitle">Figure 3-4. Accessing an echo server</h5>
<p>
<img alt="graphics/03fig04.gif" src="03fig04.gif" border="0" width="500" height="278"></p>
</center>
<pre>Hello! Enter BYE to exit.
</pre>
<p class="docText">Type anything and watch the input echo on your screen. Type
<tt>BYE</tt> (all uppercase letters) to disconnect. The server program will
terminate as well.</p>
<h4 class="docSection2Title" id="ch03lev2sec1">Serving Multiple Clients</h4>
<p class="docText">There is one problem with the simple server in the preceding
example. Suppose we want to allow multiple clients to connect to our server at
the same time. Typically, a server runs constantly on a server computer, and
clients from all over the Internet may want to use the server at the same time.
Rejecting multiple connections allows any one client to monopolize the service
by connecting to it for a long time. We can do much better through the magic of
threads.</p>
<p class="docText">Every time we know the program has established a new socket
connection, that is, when the call to accept was successful, we will launch a
new thread to take care of the connection between the server and
<span class="docEmphasis">that</span> client. The main program will just go back
and wait for the next connection. For this to happen, the main loop of the
server should look like this:</p>
<pre>while (true)
{
Socket incoming = s.accept();
Thread t = new ThreadedEchoHandler(incoming);
t.start();
}
</pre>
<p class="docText">The <tt>ThreadedEchoHandler</tt> class derives from <tt>
Thread</tt> and contains the communication loop with the client in its <tt>run</tt>
method.</p>
<pre>class ThreadedEchoHandler extends Thread
{ . . .
public void run()
{
try
{
BufferedReader in = new BufferedReader
(new InputStreamReader(incoming.getInputStream()));
PrintWriter out = new PrintWriter
(incoming.getOutputStream(), true /* autoFlush */);
String line;
while ((line = in.readLine()) != null)
{
<span class="docEmphasis">process line</span>
}
incoming.close();
}
catch(Exception e)
{
<span class="docEmphasis">handle exception</span>
}
}
}
</pre>
<p class="docText">Because each connection starts a new thread, multiple clients
can connect to the server at the same time. You can easily check out this fact.
Compile and run the server program (<a class="docLink" href="#ch03list03">Example
3-3</a>). Open several telnet windows as we have in
<a class="docLink" href="#ch03fig05">Figure 3-5</a>. You can communicate through
all of them simultaneously. The server program never dies. Use ctrl+c to kill
it.</p>
<center>
<h5 id="ch03fig05" class="docFigureTitle">Figure 3-5. Simultaneous access to the threaded echo
server</h5>
<p>
<img alt="graphics/03fig05.gif" src="03fig05.gif" border="0" width="500" height="405"></p>
</center>
<h5 id="ch03list03" class="docExampleTitle">Example 3-3 ThreadedEchoServer.java</h5>
<pre> 1. import java.io.*;
2. import java.net.*;
3.
4. /**
5. This program implements a multithreaded server that listens to
6. port 8189 and echoes back all client input.
7. */
8. public class ThreadedEchoServer
9. {
10. public static void main(String[] args )
11. {
12. try
13. {
14. int i = 1;
15. ServerSocket s = new ServerSocket(8189);
16.
17. for (;;)
18. {
19. Socket incoming = s.accept( );
20. System.out.println("Spawning " + i);
21. Thread t = new ThreadedEchoHandler(incoming, i);
22. t.start();
23. i++;
24. }
25. }
26. catch (Exception e)
27. {
28. e.printStackTrace();
29. }
30. }
31. }
32.
33. /**
34. This class handles the client input for one server socket
35. connection.
36. */
37. class ThreadedEchoHandler extends Thread
38. {
39. /**
40. Constructs a handler.
41. @param i the incoming socket
42. @param c the counter for the handlers (used in prompts)
43. */
44. public ThreadedEchoHandler(Socket i, int c)
45. {
46. incoming = i; counter = c;
47. }
48.
49. public void run()
50. {
51. try
52. {
53. BufferedReader in = new BufferedReader
54. (new InputStreamReader(incoming.getInputStream()));
55. PrintWriter out = new PrintWriter
56. (incoming.getOutputStream(), true /* autoFlush */);
57.
58. out.println( "Hello! Enter BYE to exit." );
59.
60. boolean done = false;
61. while (!done)
62. {
63. String str = in.readLine();
64. if (str == null) done = true;
65. else
66. {
67. out.println("Echo (" + counter + "): " + str);
68.
69. if (str.trim().equals("BYE"))
70. done = true;
71. }
72. }
73. incoming.close();
74. }
75. catch (Exception e)
76. {
77. e.printStackTrace();
78. }
79. }
80.
81. private Socket incoming;
82. private int counter;
83. }
</pre>
<h5 class="docSection3Title" id="ch03lev3sec1"><tt>java.net.ServerSocket</tt></h5>
<p><img alt="graphics/api.gif" src="api.gif" border="0" width="46" height="45"><br>
</p>
<ul>
<li>
<p class="docList"><tt>ServerSocket(int port) throws IOException</tt></p>
<p class="docList">creates a server socket that monitors a port.</p>
<table cellSpacing="0" cellPadding="1" width="93%" border="1">
<colgroup span="3" align="left">
</colgroup>
<tr>
<td class="docTableCell" vAlign="top"><span class="docEmphasis">
Parameters:</span> </td>
<td class="docTableCell" vAlign="top"><tt>port</tt></td>
<td class="docTableCell" vAlign="top">the port number</td>
</tr>
</table>
<p> </li>
<li>
<p class="docList"><tt>Socket accept() throws IOException</tt></p>
<p class="docList">waits for a connection. This method will block (that is,
idle) the current thread until the connection is made. The method returns a
<tt>Socket</tt> object through which the program can communicate with the
connecting client.</li>
<li>
<p class="docList"><tt>void close() throws IOException</tt></p>
<p class="docList">closes the server socket.</li>
</ul>
<h3 class="docSection1Title" id="c3s3">Sending E-Mail</h3>
<p class="docText">In this section, we show you a practical example of socket
programming: a program that sends e-mail to a remote site.</p>
<p class="docText">To send e-mail, you make a socket connection to port 25, the
SMTP port. SMTP is the Simple Mail Transport Protocol that describes the format
for e-mail messages. You can connect to any server that runs an SMTP service. On
UNIX machines, that service is typically implemented by the <tt>sendmail</tt>
daemon. However, the server must be willing to accept your request. It used to
be that sendmail servers were routinely willing to route e-mail from anyone, but
in these days of spam floods, most servers now have built-in checks and only
accept requests from users, domains, or IP address ranges that they trust.</p>
<p class="docText">Once you are connected to the server, send a mail header (in
the SMTP format, which is easy to generate), followed by the mail message.</p>
<p class="docText">Here are the details:</p>
<ol class="docList">
<li value="1">
<p class="docList">Open a socket to your host.</p>
<pre>Socket s = new Socket("mail.yourserver.com", 25); // 25 is SMTP
PrintWriter out = new PrintWriter(s.getOutputStream());
</pre>
</li>
<li value="2">
<p class="docList">Send the following information to the print stream:</p>
<pre>HELO <span class="docEmphasis">sending host</span>
MAIL FROM: <span class="docEmphasis"><sender email address></span>
RCPT TO: <span class="docEmphasis"><recipient email address></span>
DATA
<span class="docEmphasis">mail message</span>
<span class="docEmphasis">(any number of lines)</span>
.
QUIT
</pre>
</li>
</ol>
<p class="docText">The SMTP specification (RFC 821) states that lines must be
terminated with <tt>\r</tt> followed by <tt>\n</tt>.</p>
<p class="docText">Most SMTP servers do not check the veracity of the
information梱ou may be able to supply any sender you like. (Keep this in mind
the next time you get an e-mail message from <tt>president@whitehouse.gov</tt>
inviting you to a black-tie affair on the front lawn. Anyone could have
connected to an SMTP server and created a fake message.)</p>
<p class="docText">The program in <a class="docLink" href="#ch03list04">Example
3-4</a> is a very simple e-mail program. As you can see in
<a class="docLink" href="#ch03fig06">Figure 3-6</a>, you type in the sender,
recipient, mail message, and SMTP server. Then, click on the "Send" button, and
your message is sent.</p>
<center>
<h5 id="ch03fig06" class="docFigureTitle">Figure 3-6. The MailTest program</h5>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?