热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JavaUDP通信:JavaDatagramSocket类和DatagramPacket类

在TCPIP协议的传输层除了一个TCP协议之外,还有一个UDP协议。UDP协议是用户数据报协议的简称,也用于网络数据的传输。虽然UDP协议是一种不太可靠

在 TCP/IP 协议的传输层除了一个 TCP 协议之外,还有一个 UDP 协议。UDP 协议是用户数据报协议的简称,也用于网络数据的传输。虽然 UDP 协议是一种不太可靠的协议,但有时在需要较快地接收数据并且可以忍受较小错误的情况下,UDP 就会表现出更大的优势。

下面是在 Java 中使用 UDP 协议发送数据的步骤。

  1. 使用 DatagramSocket() 创建一个数据包套接字。
  2. 使用 DatagramPacket() 创建要发送的数据包。
  3. 使用 DatagramSocket 类的 send() 方法发送数据包。


接收 UDP 数据包的步骤如下:

  • 使用 DatagramSocket 创建数据包套接字,并将其绑定到指定的端口。
  • 使用 DatagramPacket 创建字节数组来接收数据包。
  • 使用 DatagramPacket 类的 receive() 方法接收 UDP 包。

DatagramPacket 类

java.net 包中的 DatagramPacket 类用来表示数据报包,数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。表 1 和表 2 简单介绍了 DatagramPacket 的构造方法和常用方法。
 

表1 DatagramPacket的构造方法
构造方法说明
DatagramPacket(byte[] buf,int length)构造 DatagramPacket,用来接收长度为 length 的数据包。
DatagramPacket(byte[] buf,int offset,
int length)
构造 DatagramPacket,用来接收长度为 length 的包,在缓
冲区中指定了偏移量。
DatagramPacket(byte[] buf,int length,
InetAddress address,int port)
构造 DatagramPacket,用来将长度为 length 的包发送到指
定主机上的指定端口。
DatagramPacket(byte[] buf,int length,
SocketAddress address)
构造数据报包,用来将长度为 length 的包发送到指定主机上
的指定端口。
DatagramPacket(byte[] buf,int offset,
int length,InetAddress address,int port)
构造 DatagramPacket,用来将长度为 length 偏移量为 offset
的包发送到指定主机上的指定端口。
DatagramPacket(byte[] buf,int offset,
int length,SocketAddress address)
构造数据报包,用来将长度为 length、偏移量为 offset 的包发
送到指定主机上的指定端口。

 

表2 DatagramPacket的常用方法
方法说明
InetAddress getAddress()返回某台机器的 IP 地址,此数据报将要发往该机器或者
从该机器接收。
byte[] getData()返回数据缓冲区。
int getLength()返回将要发送或者接收的数据的长度。
int getOffset()返回将要发送或者接收的数据的偏移量。
int getPort()返回某台远程主机的端口号,此数据报将要发往该主机或
者从该主机接收。
getSocketAddress()获取要将此包发送或者发出此数据报的远程主机的
SocketAddress(通常为 IP地址+端口号)。
void setAddress(InetAddress addr)设置要将此数据报发往的目的机器的IP地址。
void setData(byte[] buf)为此包设置数据缓冲区。
void setData(byte[] buf,int offset,
int length)
为此包设置数据缓冲区。
void setLength(int length)为此包设置长度。
void setPort(int port)设置要将此数据报发往的远程主机的端口号。
void setSocketAddress(SocketAddress
address)
设置要将此数据报发往的远程主机的
SocketAddress(通常为 IP地址+端口号)。

DatagramSocket 类

DatagramSocket 类用于表示发送和接收数据报包的套接字。数据报包套接字是包投递服务的发送或接收点。每个在数据报包套接字上发送或接收的包都是单独编址和路由的。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。

DatagramSocket 类的常用构造方法如表 3 所示。
 

表3 DatagramSocket 的构造方法
构造方法说明
DatagramSocket()构造数据报包套接字并将其绑定到本地主机上任何可用的端口。
DatagramSocket(int port)创建数据报包套接字并将其绑定到本地主机上的指定端口。
DatagramSocket(int portJnetAddress addr)创建数据报包套接字,将其绑定到指定的本地地址。
DatagramSocket(SocketAddress bindaddr)创建数据报包套接字,将其绑定到指定的本地套接字地址。


DatagramSocket 类的常用方法如表 4 所示。
 

表4 DatagramSocket 的常用方法
方法说明
void bind(SocketAddress addr)将此 DatagramSocket 绑定到特定的地址和端口。
void close()关闭此数据报包套接字。
void connect(InetAddress address,int port)将套接字连接到此套接字的远程地址。
void connect(SocketAddress addr)将此套接子连接到远程套接子地址(IP地址+端口号)。
void disconnect()断开套接字的连接。
InetAddress getInetAddress()返回此套接字连接的地址。
InetAddress getLocalAddress()获取套接字绑定的本地地址。
int getLocalPort()返回此套接字绑定的本地主机上的端口号。
int getPort()返回此套接字的端口。

例 1

编写 UDP 程序,要求客户端程序可以向服务器端发送多条数据,服务器端程序可以接收客户端发送的多条数据并将其信息输出在控制台,主要步骤如下所示。

(1) 创建一个类作为客户端,在 main() 方法定义一个 DatagramSocket 对象和一个 DatagramPacket 对象并初始化为 null。然后再定义一个 InetAddress 对象和一个端口号并分别进行初始化,代码如下所示。


  1. public static void main(String[] args)
  2. {
  3. DatagramSocket ds=null;
  4. DatagramPacket dpSend=null;
  5. InetAddress ia=InetAddress.getByName("127.0.0.1");
  6. int port=3021;
  7. }


(2) 使用 DatagramSocket 的 send(DatagramPacket p) 方法向服务器端发送数据报包,使用循环的方式完成 5 次数据的发送,每发送 1 次数据线程休眠 1000 毫秒,数据发送完毕调用 close() 方法,关闭 DatagramSocket 对象,代码如下。


  1. try
  2. {
  3. ds=new DatagramSocket();
  4. for(int i&#61;0;i<5;i&#43;&#43;)
  5. {
  6. byte[] data&#61;("我是 UDP 客户端"&#43;i).getBytes();
  7. dpSend&#61;new DatagramPacket(data,data.length,ia,port);
  8. ds.send(dpSend);
  9. Thread.sleep(1000);
  10. }
  11. ds.close();
  12. }
  13. catch(IOException | InterruptedException e)
  14. {
  15. // TODO 自动生成的 catch 块
  16. e.printStackTrace();
  17. }


(3) 创建一个类作为服务器端&#xff0c;在 main() 方法中定义一个 DatagramSocket 对象和一个 DatagramPacket 对象并初始化为 null&#xff0c;再定义一个端口号&#xff0c;代码如下所示。


  1. public static void main(String[] args)
  2. {
  3. DatagramSocket ds&#61;null;
  4. DatagramPacket dpReceive&#61;null;
  5. int port&#61;3021;
  6. }


(4) 如果成功连接到 UDP 服务器则输出“UDP 服务器已启动。。。”。循环接收客户端发送的数据&#xff0c;并将其发送的内容以及IP地址等信息输出到控制台&#xff0c;代码如下所示。


  1. try
  2. {
  3. ds&#61;new DatagramSocket(port);
  4. System.out.println("UDP服务器已启动。。。");
  5. byte[] b&#61;new byte[1024];
  6. while(ds.isClosed()&#61;&#61;false)
  7. {
  8. dpReceive&#61;new DatagramPacket(b, b.length);
  9. try
  10. {
  11. ds.receive(dpReceive);
  12. byte[] Data&#61;dpReceive.getData();
  13. int len&#61;Data.length;
  14. System.out.println("UDP客户端发送的内容是&#xff1a;" &#43; new String(Data, 0, len).trim());
  15. System.out.println("UDP客户端IP&#xff1a;" &#43; dpReceive.getAddress());
  16. System.out.println("UDP客户端端口&#xff1a;" &#43; dpReceive.getPort());
  17. }
  18. catch(IOException e)
  19. {
  20. e.printStackTrace();
  21. }
  22. }
  23. }
  24. catch(SocketException e1)
  25. {
  26. // TODO 自动生成的 catch 块
  27. e1.printStackTrace();
  28. }
  29. }


(5) 最后关闭 DatagramSocket 对象。执行服务器端程序&#xff0c;运行结果如下所示。

UDP服务器已启动。。。


(6) 再运行客户端程序&#xff0c;控制台的输出结果如下所示。

UDP客户端发送的内容是&#xff1a;我是UDP客户端0
UDP客户端IP&#xff1a;/127.0.0.1
UDP客户端端口&#xff1a;53472
UDP客户端发送的内容是&#xff1a;我是UDP客户端1
UDP客户端IP&#xff1a;/127.0.0.1
UDP客户端端口&#xff1a;53472
UDP客户端发送的内容是&#xff1a;我是UDP客户端2
UDP客户端IP&#xff1a;/127.0.0.1
UDP客户端端口&#xff1a;53472
UDP客户端发送的内容是&#xff1a;我是UDP客户端3
UDP客户端IP&#xff1a;/127.0.0.1
UDP客户端端口&#xff1a;53472
UDP客户端发送的内容是&#xff1a;我是UDP客户端4
UDP客户端IP&#xff1a;/127.0.0.1
UDP客户端端口&#xff1a;53472


推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • Python已成为全球最受欢迎的编程语言之一,然而Python程序的安全运行存在一定的风险。本文介绍了Python程序安全运行需要满足的三个条件,即系统路径上的每个条目都处于安全的位置、"主脚本"所在的目录始终位于系统路径中、若python命令使用-c和-m选项,调用程序的目录也必须是安全的。同时,文章还提出了一些预防措施,如避免将下载文件夹作为当前工作目录、使用pip所在路径而不是直接使用python命令等。对于初学Python的读者来说,这些内容将有所帮助。 ... [详细]
  • 概述H.323是由ITU制定的通信控制协议,用于在分组交换网中提供多媒体业务。呼叫控制是其中的重要组成部分,它可用来建立点到点的媒体会话和多点间媒体会议 ... [详细]
  • 在本教程中,我们将看到如何使用FLASK制作第一个用于机器学习模型的RESTAPI。我们将从创建机器学习模型开始。然后,我们将看到使用Flask创建AP ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Python操作MySQL(pymysql模块)详解及示例代码
    本文介绍了使用Python操作MySQL数据库的方法,详细讲解了pymysql模块的安装和连接MySQL数据库的步骤,并提供了示例代码。内容涵盖了创建表、插入数据、查询数据等操作,帮助读者快速掌握Python操作MySQL的技巧。 ... [详细]
  • 开源Keras Faster RCNN模型介绍及代码结构解析
    本文介绍了开源Keras Faster RCNN模型的环境需求和代码结构,包括FasterRCNN源码解析、RPN与classifier定义、data_generators.py文件的功能以及损失计算。同时提供了该模型的开源地址和安装所需的库。 ... [详细]
  • 本文介绍了协程的概念和意义,以及使用greenlet、yield、asyncio、async/await等技术实现协程编程的方法。同时还介绍了事件循环的作用和使用方法,以及如何使用await关键字和Task对象来实现异步编程。最后还提供了一些快速上手的示例代码。 ... [详细]
  • Python中的PyInputPlus模块原文:https ... [详细]
author-avatar
羽书uv吧
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有