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

📄 chap15.htm

📁 Thinking in Java, 2nd edition
💻 HTM
📖 第 1 页 / 共 5 页
字号:
            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(<font color=#004488>"END"</font>)) <font color=#0000ff>break</font>;
        System.out.println(<font color=#004488>"Echoing: "</font> + str);
        out.println(str);
      }
      System.out.println(<font color=#004488>"closing..."</font>);
    } <font color=#0000ff>catch</font>(IOException e) {
      System.err.println(<font color=#004488>"IO Exception"</font>);
    } <font color=#0000ff>finally</font> {
      <font color=#0000ff>try</font> {
        socket.close();
      } <font color=#0000ff>catch</font>(IOException e) {
        System.err.println(<font color=#004488>"Socket not closed"</font>);
      }
    }
  }
}

<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(<font color=#004488>"Server Started"</font>);
    <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>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>ServeOneJabber </B>thread takes
the <B>Socket</B> object that&#8217;s produced by <B>accept(&#160;)</B> in
<B>main(&#160;)</B> every time a new client makes a connection. Then, as before,
it creates a <B>BufferedReader</B> and auto-flushed <B>PrintWriter</B> object
using the <B>Socket</B>. Finally, it calls the special <B>Thread</B> method
<B>start(&#160;)</B>, which performs thread initialization and then calls
<B>run(&#160;)</B>. 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.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER15_I49' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER15_I50>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The responsibility for cleaning up the
socket must again be carefully designed. In this case, the socket is created
outside of the <B>ServeOneJabber</B> so the responsibility can be shared. If the
<B>ServeOneJabber</B> 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 <B>ServeOneJabber</B> object takes over responsibility for cleaning up the
thread, in its <B>run(&#160;)</B>.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER15_I50' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER15_I51>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Notice the simplicity of the
<B>MultiJabberServer</B>. As before, a <B>ServerSocket</B> is created and
<B>accept(&#160;)</B> is called to allow a new connection. But this time, the
return value of <B>accept(&#160;)</B> (a <B>Socket</B>) is passed to the
constructor for <B>ServeOneJabber,</B> which creates a new thread to handle that
connection. When the connection is terminated, the thread simply goes away.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER15_I51' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER15_I52>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">If the creation of the
<B>ServerSocket</B> fails, the exception is again thrown through
<B>main(&#160;)</B>. But if the creation succeeds, the outer <B>try-finally</B>
guarantees its cleanup. The inner <B>try-catch</B> guards only against the
failure of the <B>ServeOneJabber</B> constructor; if the constructor succeeds,
then the <B>ServeOneJabber</B> thread will close the associated socket.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER15_I52' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER15_I53>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To test that the server really does
handle multiple clients, the following program creates many clients (using
threads) that connect to the same server. The maximum number of threads allowed
is determined by the <B>final int MAX_THREADS</B>. </FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c15:MultiJabberClient.java</font>
<font color=#009900>// Client that tests the MultiJabberServer</font>
<font color=#009900>// by starting up multiple clients.</font>
<font color=#0000ff>import</font> java.net.*;
<font color=#0000ff>import</font> java.io.*;

<font color=#0000ff>class</font> JabberClientThread <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>private</font> <font color=#0000ff>static</font> <font color=#0000ff>int</font> counter = 0;
  <font color=#0000ff>private</font> <font color=#0000ff>int</font> id = counter++;
  <font color=#0000ff>private</font> <font color=#0000ff>static</font> <font color=#0000ff>int</font> threadcount = 0;
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>int</font> threadCount() { 
    <font color=#0000ff>return</font> threadcount; 
  }
  <font color=#0000ff>public</font> JabberClientThread(InetAddress addr) {
    System.out.println(<font color=#004488>"Making client "</font> + id);
    threadcount++;
    <font color=#0000ff>try</font> {
      socket = 
        <font color=#0000ff>new</font> Socket(addr, MultiJabberServer.PORT);
    } <font color=#0000ff>catch</font>(IOException e) {
      System.err.println(<font color=#004488>"Socket failed"</font>);
      <font color=#009900>// If the creation of the socket fails, </font>
      <font color=#009900>// nothing needs to be cleaned up.</font>
    }
    <font color=#0000ff>try</font> {    
      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>);
      start();
    } <font color=#0000ff>catch</font>(IOException e) {
      <font color=#009900>// The socket should be closed on any </font>
      <font color=#009900>// failures other than the socket </font>
      <font color=#009900>// constructor:</font>
      <font color=#0000ff>try</font> {
        socket.close();
      } <font color=#0000ff>catch</font>(IOException e2) {
        System.err.println(<font color=#004488>"Socket not closed"</font>);
      }
    }
    <font color=#009900>// Otherwise the socket will be closed by</font>
    <font color=#009900>// the run() method of the thread.</font>
  }
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> run() {
    <font color=#0000ff>try</font> {
      <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; 25; i++) {
        out.println(<font color=#004488>"Client "</font> + id + <font color=#004488>": "</font> + i);
        String str = in.readLine();
        System.out.println(str);
      }
      out.println(<font color=#004488>"END"</font>);
    } <font color=#0000ff>catch</font>(IOException e) {
      System.err.println(<font color=#004488>"IO Exception"</font>);
    } <font color=#0000ff>finally</font> {
      <font color=#009900>// Always close it:</font>
      <font color=#0000ff>try</font> {
        socket.close();
      } <font color=#0000ff>catch</font>(IOException e) {
        System.err.println(<font color=#004488>"Socket not closed"</font>);
      }
      threadcount--; <font color=#009900>// Ending this thread</font>
    }
  }
}

<font color=#0000ff>public</font> <font color=#0000ff>class</font> MultiJabberClient {
  <font color=#0000ff>static</font> <font color=#0000ff>final</font> <font color=#0000ff>int</font> MAX_THREADS = 40;
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) 
      <font color=#0000ff>throws</font> IOException, InterruptedException {
    InetAddress addr = 
      InetAddress.getByName(<font color=#0000ff>null</font>);
    <font color=#0000ff>while</font>(<font color=#0000ff>true</font>) {
      <font color=#0000ff>if</font>(JabberClientThread.threadCount() 
         &lt; MAX_THREADS)
        <font color=#0000ff>new</font> JabberClientThread(addr);
      Thread.currentThread().sleep(100);
    }
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>JabberClientThread</B> constructor
takes an <B>InetAddress</B> and uses it to open a <B>Socket</B>. You&#8217;re
probably starting to see the pattern: the <B>Socket</B> is always used to create
some kind of <B>Reader </B>and/or <B>Writer </B>(or <B>InputStream</B> and/or
<B>OutputStream</B>) object, which is the only way that the <B>Socket</B> can be
used. (You can, of course, write a class or two to automate this process instead
of doing all the typing if it becomes painful.) Again, <B>start(&#160;)</B>
performs thread initialization and calls <B>run(&#160;)</B>. Here, messages are
sent to the server and information from the server is echoed to the screen.
However, the thread has a limited lifetime and eventually completes. Note that
the socket is cleaned up if the constructor fails after the socket is created
but before the constructor completes. Otherwise the responsibility for calling
<B>close(&#160;)</B> for the socket is relegated to the <B>run(&#160;)</B>
method. 
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER15_I53' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER15_I54>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>threadcount</B> keeps track of how
many <B>JabberClientThread</B> objects currently exist. It is incremented as
part of the constructor and decremented as <B>run(&#160;)</B> exits (which means
the thread is terminating). In <B>MultiJabberClient.main(&#160;),</B> you can
see that the number of threads is tested, and if there are too many, no more are
created. Then the method sleeps. This way, some threads will eventually
terminate and more can be created. You can experiment with <B>MAX_THREADS</B> to
see where your particular system begins to have trouble with too many
connections.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER15_I54' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER15_I55>
</FONT><A NAME="_Toc375545498"></A><A NAME="_Toc481064871"></A><BR></P></DIV>
<A NAME="Heading519"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Datagrams<BR><A NAME="Index2090"></A><A NAME="Index2091"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The examples you&#8217;ve seen so far use
the
<A NAME="Index2092"></A><A NAME="Index2093"></A><A NAME="Index2094"></A><I>Transmission
Control Protocol</I> (TCP, also known as
<A NAME="Index2095

⌨️ 快捷键说明

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