java dategramsocket_Java使用DatagramSocket

java dategramsocket_Java使用DatagramSocketJava使用DatagramSocket代表UDP协议的Socket,DatagramSocket本身只是码头,不维护状态,不能产生IO流,它的唯一作用就是接收和发送数据报,Java使用DatagramPacket来代表数据报,DatagramSocket接收和发送的数据都是通过DatagramPacket对象完成的。先看一下DatagramSocket的构造器。DatagramSocket():…

大家好,又见面了,我是你们的朋友全栈君。

Java使用DatagramSocket代表UDP协议的Socket,DatagramSocket本身只是码头,不维护状态,不能产生IO流,它的唯一作用就是接收和发送数据报,Java使用DatagramPacket来代表数据报,DatagramSocket接收和发送的数据都是通过DatagramPacket对象完成的。

先看一下DatagramSocket的构造器。

DatagramSocket():创建一个DatagramSocket实例,并将该对象绑定到本机默认IP地址、本机所有可用端口中随机选择的某个端口。

DatagramSocket(int prot):创建一个DatagramSocket实例,并将该对象绑定到本机默认IP地址、指定端口。

DatagramSocket(int port, InetAddress laddr):创建一个DatagramSocket实例,并将该对象绑定到指定IP地址、指定端口。

通过上面三个构造器中的任意一个构造器即可创建一个DatagramSocket实例,通常在创建服务器时,创建指定端口的DatagramSocket实例–这样保证其他客户端可以将数据发送到该服务器。一旦得到了DatagramSocket实例之后,就可以通过如下两个方法来接收和发送数据。

receive(DatagramPacket p):从该DatagramSocket中接收数据报。

send(DatagramPacket p):以该DatagramSocket对象向外发送数据报。

从上面两个方法可以看出,使用DatagramSocket发送数据报时,DatagramSocket并不知道将该数据报发送到哪里,而是由DatagramPacket自身决定数据报的目的地。就像码头并不知道每个集装箱的目的地,码头只是将这些集装箱发送出去,而集装箱本身包含了该集装箱的目的地。

下面看一下DatagramPacket的构造器。

DatagramPacket(byte[] buf,int length):以一个空数组来创建DatagramPacket对象,该对象的作用是接收DatagramSocket中的数据。

DatagramPacket(byte[] buf, int length, InetAddress addr, int port):以一个包含数据的数组来创建DatagramPacket对象,创建该DatagramPacket对象时还指定了IP地址和端口–这就决定了该数据报的目的地。

DatagramPacket(byte[] buf, int offset, int length):以一个空数组来创建DatagramPacket对象,并指定接收到的数据放入buf数组中时从offset开始,最多放length个字节。

DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port):创建一个用于发送的DatagramPacket对象,指定发送buf数组中从offset开始,总共length个字节。

当Client/Server程序使用UDP协议时,实际上并没有明显的服务器端和客户端,因为两方都需要先建立一个DatagramSocket对象,用来接收或发送数据报,然后使用DatagramPacket对象作为传输数据的载体。通常固定IP地址、固定端口的DatagramSocket对象所在的程序被称为服务器,因为该DatagramSocket可以主动接收客户端数据。

在接收数据之前,应该采用上面的第一个或第三个构造器生成一个DatagramPacket对象,给出接收数据的字节数组及其长度。然后调用DatagramSocket 的receive()方法等待数据报的到来,receive()将一直等待(该方法会阻塞调用该方法的线程),直到收到一个数据报为止。如下代码所示:

//创建一个接收数据的DatagramPacket对象

DatagramPacket packet=new DatagramPacket(buf, 256);//接收数据报

socket.receive(packet);

在发送数据之前,调用第二个或第四个构造器创建DatagramPacket对象,此时的字节数组里存放了想发送的数据。除此之外,还要给出完整的目的地址,包括IP地址和端口号。发送数据是通过DatagramSocket的send()方法实现的,send()方法根据数据报的目的地址来寻径以传送数据报。如下代码所示:

//创建一个发送数据的DatagramPacket对象

DatagramPacket packet = newDatagramPacket(buf, length, address, port);//发送数据报

socket.send(packet);

使用DatagramPacket接收数据时,会感觉DatagramPacket设计得过于烦琐。开发者只关心该DatagramPacket能放多少数据,而DatagramPacket是否采用字节数组来存储数据完全不想关心。但Java要求创建接收数据用的DatagramPacket时,必须传入一个空的字节数组,该数组的长度决定了该DatagramPacket能放多少数据,这实际上暴露了DatagramPacket的实现细节。接着DatagramPacket又提供了一个getData()方法,该方法又可以返回Datagram Packet对象里封装的字节数组,该方法更显得有些多余–如果程序需要获取DatagramPacket里封装的字节数组,直接访问传给 DatagramPacket构造器的字节数组实参即可,无须调用该方法。

当服务器端(也可以是客户端)接收到一个DatagramPacket对象后,如果想向该数据报的发送者”反馈”一些信息,但由于UDP协议是面向非连接的,所以接收者并不知道每个数据报由谁发送过来,但程序可以调用DatagramPacket的如下3个方法来获取发送者的IP地址和端口。

InetAddress getAddress():当程序准备发送此数据报时,该方法返回此数据报的目标机器的IP地址;当程序刚接收到一个数据报时,该方法返回该数据报的发送主机的IP地址。

int getPort():当程序准备发送此数据报时,该方法返回此数据报的目标机器的端口;当程序刚接收到一个数据报时,该方法返回该数据报的发送主机的端口。

SocketAddress getSocketAddress():当程序准备发送此数据报时,该方法返回此数据报的目标SocketAddress;当程序刚接收到一个数据报时,该方法返回该数据报的发送主机的SocketAddress。

getSocketAddress()方法的返回值是一个SocketAddress对象,该对象实际上就是一个IP地址和一个端口号。也就是说,SocketAddress对象封装了一个InetAddress对象和一个代表端口的整数,所以使用SocketAddress对象可以同时代表IP地址和端口。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/133131.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Vim查找命令及快捷键

    Vim查找命令及快捷键Vim查找命令及快捷键一、通过指令查找 1、左斜杠/ 从光标所在位置向文件尾搜索  例:/hello   2、问号? 从光标所在位置向文件头搜索  例:/hello   注:/和?均可加参数做指定查找(两者搜索方向不同,此处以/举例进行说明)    1) \<匹配单词的开头 \>匹配单词的结尾  例: \<hel

  • Servlet中的GET和POST之间的区别

    Servlet中的GET和POST之间的区别

  • css left right_leftorright什么意思

    css left right_leftorright什么意思零、说点什么好久没更新了。并不是在折腾什么大作,而是广度学习与实践中,加上婚礼等诸多大事,所以产出较少。今天这篇也只是小作,博客是自己很好的学习工具,只要我学习不止,博客也会不断更新的。我们平时一般都使用clear:both清除浮动,貌似就干这一件事件。用得很开心,但似乎理解上懵懵懂懂,我其实也是,早年的时候,测试过CSS clear:left/right,虽知其作用(

  • rsyslog日志服务器_php日志系统

    rsyslog日志服务器_php日志系统特性介绍:http://www.rsyslog.com/features/下载: http://www.rsyslog.com/download/本文内容来源于:http://blog.csdn.net/xiangliangyu2008/article/details/8102064===========================

  • js 刷新当前页面

    js 刷新当前页面方法1:reload()方法reload()方法用于刷新当前文档。reload()方法类似于你浏览器上的刷新页面按钮。location.reload();方法2:replace()方法replace()方法可用一个新文档取代当前文档。<!DOCTYPEhtml><html><head><metacharset=”utf-8″><title>菜鸟教程(runoob.com)</title><sc

  • Git安装配置教程

    Git安装配置教程1.Git简介Git是一个开源的分布式版本控制系统,可以有效、高速的处理从很小到非常大的项目版本管理1。Git是LinusTorvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。2.Git工作示意图3.Windows下安装Git3.1Git下载下载地址:https://git-for-windows.github.io/下载有时候很慢,请耐心

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号