按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
有维护工作都转到代码行中进行。此外,程序片要用一个线程监视由服务器传回的响应信息,而非实现
Runnable 接口,用集成到程序片的一个独立线程来做这件事情。当然,这样做对代码的可读性不利,但却能
产生一个单类(以及单个服务器请求)程序片:
//: NameSender。java
// An applet that sends an email address
// as a datagram; using Java 1。02。
import java。awt。*;
import java。applet。*;
import java。*;
import java。io。*;
public class NameSender extends Applet
implements Runnable {
private Thread pl = null;
556
…………………………………………………………Page 558……………………………………………………………
private Button send = new Button(
〃Add email address to mailing list〃);
private TextField t = new TextField(
〃type your email address here〃; 40);
private String str = new String();
private Label
l = new Label(); l2 = new Label();
private DatagramSocket s;
private InetAddress hostAddress;
private byte'' buf =
new byte'NameCollector。BUFFER_SIZE';
private DatagramPacket dp =
new DatagramPacket(buf; buf。length);
private int vcount = 0;
public void init() {
setLayout(new BorderLayout());
Panel p = new Panel();
p。setLayout(new GridLayout(2; 1));
p。add(t);
p。add(send);
add(〃North〃; p);
Panel labels = new Panel();
labels。setLayout(new GridLayout(2; 1));
labels。add(l);
labe ls。add(l2);
add(〃Center〃; labels);
try {
// Auto…assign port number:
s = new DatagramSocket();
hostAddress = InetAddress。getByName(
getCodeBase()。getHost());
} catch(UnknownHostException e) {
l。setText(〃Cannot find host〃);
} catch(SocketException e) {
l。setText(〃Can't open socket〃);
}
l。setText(〃Ready to send your email address〃);
}
public boolean action (Event evt; Object arg) {
if(evt。target。equals(send)) {
if(pl != null) {
// pl。stop(); Deprecated in Java 1。2
Thread remove = pl;
pl = null;
remove。interrupt();
}
l2。setText(〃〃);
// Check for errors in email name:
str = t。getText()。toLowerCase()。trim();
if(str。indexOf(' ') != …1) {
l。setText(〃Spaces not allowed in name〃);
return true;
557
…………………………………………………………Page 559……………………………………………………………
}
if(str。indexOf(';') != …1) {
l。setText(〃mas not allowed in name〃);
return true;
}
if(str。indexOf('@') == …1) {
l。setText(〃Name must include '@'〃);
l2。setText(〃〃);
return true;
}
if(str。indexOf('@') == 0) {
l。setText(〃Name must preceed '@'〃);
l2。setText(〃〃);
return true;
}
String end =
str。substring(str。indexOf('@'));
if(end。indexOf('。') == …1) {
l。setText(〃Portion after '@' must 〃 +
〃have an extension; such as '。'〃);
l2。setText(〃〃);
return true;
}
// Everything's OK; so send the name。 Get a
// fresh buffer; so it's zeroed。 For some
// reason you must use a fixed size rather
// than calculating the size dynamically:
byte'' sbuf =
new byte'NameCollector。BUFFER_SIZE';
str。getBytes(0; str。length(); sbuf; 0);
DatagramPacket toSend =
new DatagramPacket(
sbuf; 100; hostAddress;
NameCollector。COLLECTOR_PORT);
try {
s。send(toSend);
} catch(Exception e) {
l。setText(〃Couldn't send datagram〃);
return true;
}
l。setText(〃Sent: 〃 + str);
send。setLabel(〃Re…send〃);
pl = new Thread(this);
pl。start();
l2。setText(
〃Waiting for verification 〃 + ++vcount);
}
else return super。action(evt; arg);
return true;
}
// The thread portion of the applet watches for
// the reply to e back from the server:
558
…………………………………………………………Page 560……………………………………………………………
public void run() {
try {
s。receive(dp);
} catch(Exception e) {
l2。setText(〃Couldn't receive datagram〃);
return;
}
l2。setText(new String(dp。getData();
0; 0; dp。getLength()));
}
} ///:~
程序片的UI (用户界面)非常简单。它包含了一个TestField (文本字段),以便我们键入一个电子函件地
址;以及一个Button (按钮),用于将地址发给服务器。两个Label (标签)用于向用户报告状态信息。
到现在为止,大家已能判断出DatagramSocket、InetAddress、缓冲区以及DatagramPacket 都属于网络连接
中比较麻烦的部分。最后,大家可看到run()方法实现了线程部分,使程序片能够“侦听”由服务器传回的
响应信息。
init()方法用大家熟悉的布局工具设置 GUI,然后创建 DatagramSocket,它将同时用于数据报的收发。
action()方法只负责监视我们是否按下了“发送”(send)按钮。记住,我们已被限制在Java 1。0 上面,所
以不能再用较灵活的内部类了。按钮按下以后,采取的第一项行动便是检查线程pl,看看它是否为null
(空)。如果不为null ,表明有一个活动线程正在运行。消息首次发出时,会启动一个新线程,用它监视来
自服务器的回应。所以假若有个线程正在运行,就意味着这并非用户第一次发送消息。pl 句柄被设为 null,
同时中止原来的监视者(这是最合理的一种做法,因为stop()已被Java 1。2 “反对”,这在前一章已解释过
了)。
无论这是否按钮被第一次按下,I2 中的文字都会清除。
下一组语句将检查E…mail 名字是否合格。String。indexOf()方法的作用是搜索其中的非法字符。如果找到一
个,就把情况报告给用户。注意进行所有这些工作时,都不必涉及网络通信,所