疯狂Java讲义:使用DatagramSocket发送、接收数据[2]

疯狂Java讲义:使用DatagramSocket发送、接收数据[2],第1张

程序客户端代码也与此类似 客户端采用循环不断地读取用户键盘输入 每当读到用户输入内容后就将该内容封装成DatagramPacket数据报 再将该数据报发送出去 接着把DatagramSocket中的数据读入接收用的DatagramPacket中(实际上是读入该DatagramPacket所封装的字节数组中) 客户端代码如下

程序清单 codes/ / /UdpClient java

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 inBuff length)

//定义一个用于发送的DatagramPacket对象

private DatagramPacket outPacket = null

public void init()throws IOException

{

try

{

//创建一个客户端DatagramSocket 使用随机端口

socket = new DatagramSocket()

//初始化发送用的DatagramSocket 它包含一个长度为 的字节数组

outPacket = new DatagramPacket(new byte[ ]

InetAddress getByName(DEST_IP) DEST_PORT)

//创建键盘输入流

Scanner scan = new Scanner(System in)

//不断读取键盘输入

while(scan hasNextLine())

{

//将键盘输入的一行字符串转换字节数组

byte[] buff = scan nextLine() getBytes()

//设置发送用的DatagramPacket里的字节数据

outPacket setData(buff)

//发送数据报

socket send(outPacket)

//读取Socket中的数据 读到的数据放在inPacket所封装的字节数组里

socket receive(inPacket)

System out println(new String(inBuff

inPacket getLength()))

}

}

//使用finally块保证关闭资源

finally

{

if (socket != null)

{

socket close()

}

}

}

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程序设计培训视频教程

lishixinzhi/Article/program/Java/hx/201311/27260

Java中封装了大量的socket API 为编写网络通信程序提供了极大的方便 在计算机网络的学习中 大家都已熟练掌握了TCP/UDP的基本原理 在此不在赘述 仅给出接收端和发送端的源代码 供大家讨论学习 发送端代码如下:import java io *import java lang *import *public class uclient{private DatagramSocket cliprivate DatagramPacket pacprivate byte *** []private String senpublic uclient(){Init()}public void Init(){try{//指定端口号 避免与其他应用程序发生冲突cli=new DatagramSocket( )*** =new byte[ ]sen= UDP方式发送数据 *** =sen getBytes()pac=new DatagramPacket( *** *** length InetAddress getByName( localhost ) )cli send(pac)}catch(SocketException se){se printStackTrace()}catch(IOException ie){ie printStackTrace()}}public static void main(String args[]){new uclient()}}接收端数据:import java io *import java lang *import *public class userve{private DatagramSocket serprivate DatagramPacket pacprivate byte rb[]private String revpublic userve(){Init()}public void Init(){try{ser=new DatagramSocket( )rb=new byte[ ]pac=new DatagramPacket(rb rb length)rev= int i= while(i== )//无数据 则循环{ser receive(pac)i=pac getLength()//接收数据if(i>){//指定接收到数据的长度 可使接收数据正常显示 开始时很容易忽略这一点rev=new String(rb pac getLength())System out println(rev)i= //循环接收}}}catch(Exception e){e printStackTrace()}}public static void main(String args[]){new userve()}} lishixinzhi/Article/program/Java/hx/201311/26023


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/11462340.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-16
下一篇 2023-05-16

发表评论

登录后才能评论

评论列表(0条)

保存