程序客户端代码也与此类似客户端采用循环不断地读取用户键盘输入每当读到用户输入内容后就将该内容封装成DatagramPacket数据报再将该数据报发送出去接着把DatagramSocket中的数据读入接收用的DatagramPacket中(实际上是读入该DatagramPacket所封装的字节数组中)客户端代码如下
程序清单codes///UdpClientjava
public class UdpClient
{
//定义发送数据报的目的地
public static final int DEST_PORT = ;
public static final String DEST_IP = ;
//定义每个数据报的最大大小为K
private static final int DATA_LEN = ;
//定义该客户端使用的DatagramSocket
private DatagramSocket socket = null;
//定义接收网络数据的字节数组
byte[] inBuff = new byte[DATA_LEN];
//以指定字节数组创建准备接受数据的DatagramPacket对象
private DatagramPacket inPacket =
new DatagramPacket(inBuff inBufflength)
//定义一个用于发送的DatagramPacket对象
private DatagramPacket outPacket = null;
public void init()throws IOException
{
try
{
//创建一个客户端DatagramSocket使用随机端口
socket = new DatagramSocket()
//初始化发送用的DatagramSocket它包含一个长度为的字节数组
outPacket = new DatagramPacket(new byte[]
InetAddressgetByName(DEST_IP) DEST_PORT)
//创建键盘输入流
Scanner scan = new Scanner(Systemin)
//不断读取键盘输入
while(scanhasNextLine())
{
//将键盘输入的一行字符串转换字节数组
byte[] buff = scannextLine()getBytes()
//设置发送用的DatagramPacket里的字节数据
outPacketsetData(buff)
//发送数据报
socketsend(outPacket)
//读取Socket中的数据读到的数据放在inPacket所封装的字节数组里
socketreceive(inPacket)
Systemoutprintln(new String(inBuff
inPacketgetLength()))
}
}
//使用finally块保证关闭资源
finally
{
if (socket != null)
{
socketclose()
}
}
}
public static void main(String[] args)
throws IOException
{
new UdpClient()init()
}
}
上面程序的粗体字代码同样也是通过DatagramSocket发送接收DatagramPacket的关键代码这些代码与服务器的代码基本相似而客户端与服务器端的唯一区别在于服务器所在IP地址端口是固定的所以客户端可以直接将该数据报发送给服务器而服务器则需要根据接收到的数据报来决定将反馈数据报的目的地
读者可能会发现使用DatagramSocket进行网络通信时服务器端无须也无法保存每个客户端的状态客户端把数据报发送到服务器后完全有可能立即退出但不管客户端是否退出服务器无法知道客户端的状态
当使用UDP协议时如果想让一个客户端发送的聊天信息可被转发到其他所有客户端则比较困难可以考虑在服务器使用Set来保存所有客户端信息每当接收到一个客户端的数据报之后程序检查该数据报的源SocketAddress是否在Set集合中如果不在就将该SocketAddress添加到该Set集合中但这样一来又涉及一个问题可能有些客户端发送一个数据报之后永久性地退出了程序但服务器端还将该客户端的SocketAddress保存在Set集合中……总之这种方式需要处理的问题比较多编程比较烦琐幸好Java为UDP协议提供了MulticastSocket类通过该类可以轻松实现多点广播
返回目录疯狂Java讲义
编辑推荐
Java程序性能优化让你的Java程序更快更稳定
新手学Java 编程
Java程序设计培训视频教程
[] []