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

📄 tij0166.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 3 页
字号:
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>getAddress(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>getPort(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>before</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
you send the datagram (in which case it tells the address and port of this
machine, the one the datagram is being sent from). This is an essential part of
datagrams: you don&#8217;t need to keep track of where a message came from
because it&#8217;s always stored inside the datagram. In fact, the most
reliable way to program is if you don&#8217;t try to keep track, but instead
always extract the address and port from the datagram in question (as is done
here).
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">To
test this server, here&#8217;s a program that makes a number of clients, all of
which fire datagram packets to the server and wait for the server to echo them
back.
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: ChatterClient.java</font>
<font color="#009900">// Tests the ChatterServer by starting multiple </font>
<font color="#009900">// clients, each of which sends datagrams.</font>
<font color="#0000ff">import</font> java.lang.Thread;
<font color="#0000ff">import</font> java.net.*;
<font color="#0000ff">import</font> java.io.*;

<font color="#0000ff">public</font> <font color="#0000ff">class</font> ChatterClient <font color="#0000ff">extends</font> Thread {
  <font color="#009900">// Can listen &amp; send on the same socket:</font>
  <font color="#0000ff">private</font> DatagramSocket s;
  <font color="#0000ff">private</font> InetAddress hostAddress;
  <font color="#0000ff">private</font> <font color="#0000ff">byte</font>[] buf = <font color="#0000ff">new</font> <font color="#0000ff">byte</font>[1000];
  <font color="#0000ff">private</font> DatagramPacket dp = 
    <font color="#0000ff">new</font> DatagramPacket(buf, buf.length);
  <font color="#0000ff">private</font> <font color="#0000ff">int</font> id;

  <font color="#0000ff">public</font> ChatterClient(<font color="#0000ff">int</font> identifier) {
    id = identifier;
    <font color="#0000ff">try</font> {
      <font color="#009900">// Auto-assign port number:</font>
      s = <font color="#0000ff">new</font> DatagramSocket();
      hostAddress = 
        InetAddress.getByName("localhost");
    } <font color="#0000ff">catch</font>(UnknownHostException e) {
      System.err.println("Cannot find host");
      System.exit(1);
    } <font color="#0000ff">catch</font>(SocketException e) {
      System.err.println("Can't open socket");
      e.printStackTrace();
      System.exit(1);
    } 
    System.out.println("ChatterClient starting");
  }
  <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++) {
        String outMessage = "Client #" +
          id + ", message #" + i;
        <font color="#009900">// Make and send a datagram:</font>
        s.send(Dgram.toDatagram(outMessage,
          hostAddress, 
          ChatterServer.INPORT));
        <font color="#009900">// Block until it echoes back:</font>
        s.receive(dp);
        <font color="#009900">// Print out the echoed contents:</font>
        String rcvd = "Client #" + id +
          ", rcvd from " + 
          dp.getAddress() + ", " + 
          dp.getPort() + ": " +
          Dgram.toString(dp);
        System.out.println(rcvd);
      }
    } <font color="#0000ff">catch</font>(IOException e) {
      e.printStackTrace();
      System.exit(1);
    }
  }
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
    <font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i &lt; 10; i++)
      <font color="#0000ff">new</font> ChatterClient(i).start();
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ChatterClient</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is created as a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Thread</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
so that multiple clients can be made to bother the server. Here you can see
that the receiving 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DatagramPacket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
looks just like the one used for 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ChatterServer</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
In the constructor, the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DatagramSocket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is created with no arguments since it doesn&#8217;t need to advertise itself as
being at a particular port number. The Internet address used for this socket
will be &#8220;this machine&#8221; (for the example, 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>localhost</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">)
and the port number will be automatically assigned, as you will see from the
output. This 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DatagramSocket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
like the one for the server, will be used both for sending and receiving.
</FONT><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>hostAddress</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is the Internet address of the host machine you want to talk to. The one part
of the program in which you must know an exact Internet address and port number
is the part in which you make the outgoing 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DatagramPacket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
As is always the case, the host must be at a known address and port number so
that clients can originate conversations with the host.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Each
thread is given a unique identification number (although the port number
automatically assigned to the thread would also provide a unique identifier). In 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>run(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
a message 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is created that contains the thread&#8217;s identification number and the
message number this thread is currently sending. This 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is used to create a datagram that is sent to the host at its address; the port
number is taken directly from a constant in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ChatterServer</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Once the message is sent, 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>receive(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
blocks until the server replies with an echoing message. All of the information
that&#8217;s shipped around with the message allows you to see that what comes
back to this particular thread is derived from the message that originated from
it. In this example, even though UDP is an &#8220;unreliable&#8221; protocol,
you&#8217;ll see that all of the datagrams get where they&#8217;re supposed to.
(This will be true for localhost and LAN situations, but you might begin to see
some failures for non-local connections.)
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">When
you run this program, you&#8217;ll see that each of the threads finishes, which
means that each of the datagram packets sent to the server is turned around and
echoed to the correct recipient; otherwise one or more threads would hang,
blocking until their input shows up.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
might think that the only right way to, for example, transfer a file from one
machine to another is through TCP sockets, since they&#8217;re
&#8220;reliable.&#8221; However, because of the speed of datagrams they can
actually be a better solution. You simply break the file up into packets and
number each packet. The receiving machine takes the packets and reassembles
them; a &#8220;header packet&#8221; tells the machine how many to expect and
any other important information. If a packet is lost, the receiving machine
sends a datagram back telling the sender to retransmit.
</FONT><a name="_Toc408018772"></a><P></DIV>
<HR><DIV ALIGN=LEFT><A NAME="fn64" HREF="#fnB64">[64]</A><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black">
TCP and UDP ports are considered unique. That is, you can simultaneously run a
TCP and UDP server on port 8080 without interference.
</FONT><P></DIV>


<div align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0165.html">Prev</a> | <a href="tij0167.html">Next</a>
</div>
</body></html>

⌨️ 快捷键说明

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