📄 tij0166.html
字号:
<font color="#009900">// return new String(p.getData(), </font>
<font color="#009900">// 0, 0, p.getLength());</font>
<font color="#009900">// The Java 1.1 approach:</font>
<font color="#0000ff">return</font>
<font color="#0000ff">new</font> String(p.getData(), 0, p.getLength());
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
first method of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Dgram</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
takes a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
an
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>InetAddress,</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and a port number and builds a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DatagramPacket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
by copying the contents of the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
into a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>byte</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
buffer and passing the buffer into the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DatagramPacket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
constructor. Notice the “+1” in the buffer allocation – this
was necessary to prevent truncation. The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>getBytes( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is a special operation that copies the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>char</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s
of a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
into a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>byte</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
buffer. This method is now deprecated; Java 1.1<A NAME="Index2681"></A>
has a “better” way to do this but it’s commented out here
because it truncates the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
So you’ll get a deprecation message when you compile it under Java 1.1,
but the behavior will be correct. (This bug might be fixed by the time you read
this.)
</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>Dgram.toString( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method shows both the Java 1.0<A NAME="Index2682"></A>
approach and the Java 1.1 approach (which is different because there’s a
new kind of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
constructor).
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Here
is the server for the datagram demonstration:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: ChatterServer.java</font>
<font color="#009900">// A server that echoes datagrams</font>
<font color="#0000ff">import</font> java.net.*;
<font color="#0000ff">import</font> java.io.*;
<font color="#0000ff">import</font> java.util.*;
<font color="#0000ff">public</font> <font color="#0000ff">class</font> ChatterServer {
<font color="#0000ff">static</font> <font color="#0000ff">final</font> <font color="#0000ff">int</font> INPORT = 1711;
<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="#009900">// Can listen & send on the same socket:</font>
<font color="#0000ff">private</font> DatagramSocket socket;
<font color="#0000ff">public</font> ChatterServer() {
<font color="#0000ff">try</font> {
socket = <font color="#0000ff">new</font> DatagramSocket(INPORT);
System.out.println("Server started");
<font color="#0000ff">while</font>(<font color="#0000ff">true</font>) {
<font color="#009900">// Block until a datagram appears:</font>
socket.receive(dp);
String rcvd = Dgram.toString(dp) +
", from address: " + dp.getAddress() +
", port: " + dp.getPort();
System.out.println(rcvd);
String echoString =
"Echoed: " + rcvd;
<font color="#009900">// Extract the address and port from the</font>
<font color="#009900">// received datagram to find out where to</font>
<font color="#009900">// send it back:</font>
DatagramPacket echo =
Dgram.toDatagram(echoString,
dp.getAddress(), dp.getPort());
socket.send(echo);
}
} <font color="#0000ff">catch</font>(SocketException e) {
System.err.println("Can't open socket");
System.exit(1);
} <font color="#0000ff">catch</font>(IOException e) {
System.err.println("Communication error");
e.printStackTrace();
}
}
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
<font color="#0000ff">new</font> ChatterServer();
}
} <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>ChatterServer</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
contains a single
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DatagramSocket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
for receiving messages, instead of creating one each time you’re ready to
receive a new message. The single
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DatagramSocket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
can be used repeatedly. This
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DatagramSocket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
has a port number because this is the server and the client must have an exact
address where it wants to send the datagram. It is given a port number but not
an Internet address because it resides on “this” machine so it
knows what its Internet address is (in this case, the default
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>localhost</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">).
In the infinite
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>while</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
loop, the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>socket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is told to <A NAME="Index2683"></A><A NAME="Index2684"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>receive( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
whereupon it blocks until a datagram shows up, and then sticks it into our
designated receiver, the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DatagramPacket
dp
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
The packet is converted to a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
along with information about the Internet address and socket where the packet
came from. This information is displayed, and then an extra string is added to
indicate that it is being echoed back from the server.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Now
there’s a bit of a quandary. As you will see, there are potentially many
different Internet addresses and port numbers that the messages might come from
– that is, the clients can reside on any machine. (In this demonstration
they all reside on the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>localhost</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
but the port number for each client is different.) To send a message back to
the client that originated it, you need to know that client’s Internet
address and port number. Fortunately, this information is conveniently packaged
inside the <A NAME="Index2685"></A><A NAME="Index2686"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DatagramPacket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that sent the message, so all you have to do is pull it out using <A NAME="Index2687"></A><A NAME="Index2688"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>getAddress( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and <A NAME="Index2689"></A><A NAME="Index2690"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>getPort( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which are used to build the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DatagramPacket</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>echo</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that is sent back through the same socket that’s doing the receiving. In
addition, when the socket sends the datagram, it automatically adds the
Internet address and port information of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>this</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
machine, so that when the client receives the message, it can use
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>getAddress( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>getPort( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to find out where the datagram came from. In fact, the only time that
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>getAddress( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>getPort( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
don’t tell you where the datagram came from is if you create a datagram
to send and you call
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -