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

📄 tij0165.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<html><body>

<table width="100%"><tr>
<td>
<a href="http://www.bruceeckel.com/javabook.html">Bruce Eckel's Thinking in Java</a>
</td>
<td align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0164.html">Prev</a> | <a href="tij0166.html">Next</a>
</td>
</tr></table>
<hr>

<H2 ALIGN=LEFT>
Serving
multiple clients
<P><A NAME="Index2658"></A></H2>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>JabberServer</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
works, but it can handle only one client at a time. In a typical server,
you&#8217;ll want to be able to deal with many clients at once. The answer is <A NAME="Index2659"></A><A NAME="Index2660"></A>multithreading,
and in languages that don&#8217;t directly support multithreading this means
all sorts of complications. In Chapter 14 you saw that multithreading in Java
is about as simple as possible, considering that multithreading is a rather
complex topic. Because threading in Java is reasonably straightforward, making
a server that handles multiple clients is relatively easy.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
basic scheme is to make a single 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ServerSocket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in the server and call 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>accept(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to wait for a new connection. When 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>accept(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
returns, you take the resulting 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Socket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and use it to create a new thread whose job is to serve that particular client.
Then you call 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>accept(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
again to wait for a new client.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
the following server code, you can see that it looks similar to the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>JabberServer.java</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
example except that all of the operations to serve a particular client have
been moved inside a separate thread class:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: MultiJabberServer.java</font>
<font color="#009900">// A server that uses multithreading to handle </font>
<font color="#009900">// any number of clients.</font>
<font color="#0000ff">import</font> java.io.*;
<font color="#0000ff">import</font> java.net.*;

<font color="#0000ff">class</font> ServeOneJabber <font color="#0000ff">extends</font> Thread {
  <font color="#0000ff">private</font> Socket socket;
  <font color="#0000ff">private</font> BufferedReader in;
  <font color="#0000ff">private</font> PrintWriter out;
  <font color="#0000ff">public</font> ServeOneJabber(Socket s) 
      <font color="#0000ff">throws</font> IOException {
    socket = s;
    in = 
      <font color="#0000ff">new</font> BufferedReader(
        <font color="#0000ff">new</font> InputStreamReader(
          socket.getInputStream()));
    <font color="#009900">// Enable auto-flush:</font>
    out = 
      <font color="#0000ff">new</font> PrintWriter(
        <font color="#0000ff">new</font> BufferedWriter(
          <font color="#0000ff">new</font> OutputStreamWriter(
            socket.getOutputStream())), <font color="#0000ff">true</font>);
    <font color="#009900">// If any of the above calls throw an </font>
    <font color="#009900">// exception, the caller is responsible for</font>
    <font color="#009900">// closing the socket. Otherwise the thread</font>
    <font color="#009900">// will close it.</font>
    start(); <font color="#009900">// Calls run()</font>
  }
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> run() {
    <font color="#0000ff">try</font> {
      <font color="#0000ff">while</font> (<font color="#0000ff">true</font>) {  
        String str = in.readLine();
        <font color="#0000ff">if</font> (str.equals("END")) <font color="#0000ff">break</font>;
        System.out.println("Echoing: " + str);
        out.println(str);
      }
      System.out.println("closing...");
    } <font color="#0000ff">catch</font> (IOException e) {
    } <font color="#0000ff">finally</font> {
      <font color="#0000ff">try</font> {
        socket.close();
      } <font color="#0000ff">catch</font>(IOException e) {}
    }
  }
}

<font color="#0000ff">public</font> <font color="#0000ff">class</font> MultiJabberServer {  
  <font color="#0000ff">static</font> <font color="#0000ff">final</font> <font color="#0000ff">int</font> PORT = 8080;
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args)
      <font color="#0000ff">throws</font> IOException {
    ServerSocket s = <font color="#0000ff">new</font> ServerSocket(PORT);
    System.out.println("Server Started");
    <font color="#0000ff">try</font> {
      <font color="#0000ff">while</font>(<font color="#0000ff">true</font>) {
        <font color="#009900">// Blocks until a connection occurs:</font>
        Socket socket = s.accept();
        <font color="#0000ff">try</font> {
          <font color="#0000ff">new</font> ServeOneJabber(socket);
        } <font color="#0000ff">catch</font>(IOException e) {
          <font color="#009900">// If it fails, close the socket,</font>
          <font color="#009900">// otherwise the thread will close it:</font>
          socket.close();
        }
      }
    } <font color="#0000ff">finally</font> {
      s.close();
    }
  } 
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ServeOneJabber
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">thread
takes the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Socket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object that&#8217;s produced by 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>accept(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>main(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
every time a new client makes a connection. Then, as before, it creates a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>BufferedReader</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and auto-flushed 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>PrintWriter</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object using the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Socket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Finally, it calls the special 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Thread</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>start(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which performs thread initialization and then calls 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>run(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
This performs the same kind of action as in the previous example: reading
something from the socket and then echoing it back until it reads the special
&#8220;END&#8221; signal.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
responsibility for cleaning up the socket must again be carefully designed. In
this case, the socket is created outside of the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ServeOneJabber</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
so the responsibility can be shared. If the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ServeOneJabber</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
constructor fails, it will just throw the exception to the caller, who will
then clean up the thread. But if the constructor succeeds, then the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ServeOneJabber</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object takes over responsibility for cleaning up the thread, in its 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>run(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Notice
the simplicity of the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>MultiJabberServer</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
As before, a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ServerSocket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is created and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>accept(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is called to allow a new connection. But this time, the return value of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>accept(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Socket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">)
is passed to the constructor for 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ServeOneJabber,</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
which creates a new thread to handle that connection. When the connection is
terminated, the thread simply goes away.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">If

⌨️ 快捷键说明

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