您的位置:首页 > 编程语言

如何应用DataGram进行用户-服务器编程

2009-05-13 03:32 429 查看

《Java编程艺术》章节选登。作者:高永强
清华大学出版社
(即将出版)


23.2.5 Datagram编程 (1)

数据报表Datagram,或称数报式数据传输技术,利用UDP通讯协议(User Datagram Protocol),进行用户-服务器间的数据传递,但Java虚拟机将UDP 底层通讯细节隐藏,编程人员不必顾及其通讯协议和过程,只需利用java.net包中提供的API类DatagramSocket和DatagramPacket进行程序设计,调用适当的方法,实现用户-服务器编程。其中DatagrameScoket用来创建端口间的通讯,而DatagramPacket用来获取通过网络地址和端口以邮包方式(Packet)发送来的信息。表23.4列出了java.net包中DataramSocket和DataramPacket的常用构造器以及方法。
表23.4 DatagramSocket和DatagramPacket类的常用构造器以及方法
[align=\"center\"]构造器/方法[/align]
[align=\"center\"]解 释[/align]
[align=\"left\"]DatagramSocket(int port,InetAdrress address)[/align]
按指定端口和互联网地址创建对象。
close()
关闭插座连接。
connect(InetAddress address, int port)
按指定互联网地址和端口连接。
disconnect()
断开当前的连接。
InetAddress getInetAddress()
返回当前数报插座的互联网地址。
InetAddress getLocalAddress()
返回当前数报插座的本机地址
int getPort()
返回当前数报插座的连接端口。
int getLocalPort()
返回当前数报插座的本机连接端口。
receive(DatagramPacket packet)
接收当前数报插座的邮件。
send(DatagramPacket packet)
发送当前数报插座的邮件。
DatagramPacket(byte[] buf,
int length)
按指定缓冲数组合长度创建获取邮包的对象。
InetAddress getAddress()
返回当前进行邮包传送的互联网地址。
Byte[] getData()
返回当前发送或接收数据缓冲数组。
int getLength()
返回当前发送或接收数据的长度。
int getPort()
返回当前发送或接收数据的端口。

注意 DatagramSocket和DatagramPacket抛出检查性异常,程序中必须提供处理这些异常的代码。具体实例见下面的讨论。

下面的例子利用DatagramSocket和DatagramPacket,模拟用户-服务器通讯,将用户 的英文输入,通过邮包发送到服务器端程序,转换为大写字母,并将结果传回到用户屏 幕。其功能类似于在Socket和ServerSocket讨论过的程序,但增加了统计并返回邮包长度的操作。图23.7显示了这个例子的一个典型运行结果。图上方为服务器端程序运行后的截图。(注:截图未能显示。请参考原书)





图23.7 利用Datagram的典型运行结果
如下是利用Datagram编写的服务器端程序的代码:

//这个程序存在本书配套资源目录Ch23名为DatagramServerTest.java
import java.io.*;
import java.net.*;
public class DatagramServerTest {
public
static void main(String[] args) {
System.out.println(\"Welcome! The server
is running....\");
String line = \"Datagram packet from server: I
love Java programming.\\n\";
String
promptString = line.toUpperCase() + \"Enter quit to STOP\";
try {
DatagramSocket socket = new
DatagramSocket(1688);
//创建指定端口的Datagram
DatagramPacket receivePacket; //声明接收邮包
byte[] buf = new byte[256]; //缓冲器
receivePacket = new DatagramPacket(buf,
buf.length);
//创建接收邮包
socket.receive(receivePacket); //接收邮包
buf = promptString.getBytes(); //内容至缓冲
InetAddress address =
receivePacket.getAddress();
//得到接收地址
int port = receivePacket.getPort();//得到接收端口
sending(socket, buf, buf.length, address,
port);
//调用发送邮包方法
while (true) {
buf = new byte[256]; //清除缓冲
receivePacket = new DatagramPacket(buf,
buf.length);
//创建新邮包
socket.receive(receivePacket); //接收
String receive = new
String(receivePacket.getData()); //得到邮包内容
buf = receive.toUpperCase().getBytes();
//内容转成大写并送往缓冲
sending(socket, buf, buf.length, address,
port);//发送
buf = new byte[256]; //清除缓冲
String
wordCount = \"(Converting from server and packet length: \" + receive.trim().length() +
\")\";
receivePacket
= new DatagramPacket(buf, buf.length); //创建新邮包
socket.receive(receivePacket); //接收
buf =
wordCount.getBytes(); //发件内容送往缓冲
sending(socket, buf, buf.length, address,
port);
//调用发送方法
}
}
catch (IOException e) {
e.printStackTrace();
}
}
//发送邮件方法
public static void sending(DatagramSocket socket, byte[] buf, int
length, InetAddress address, int port) {
DatagramPacket sendPacket = new DatagramPacket(buf, length, address, port);
try {
socket.send(sendPacket); //发送
}catch (IOException e) {
e.printStackTrace();
}
}
}

代码中首先接收用户端发送过来的一个空邮包,并利用这个邮包发送慰问和提示信息到用户。在循环中,接收用户发来的邮包内容,并将其转换成大写字母、统计字符串即邮包长度,调用自定义静态方法sending()将结果邮包发还给发来的用户。代码中在重新利用缓冲器发送新内容时,利用重新定义缓冲器来清除其原有内容。(待续)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐