Java使用DatagramSocket
转自:http://book.51cto.com/art/201203/322540.htm
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 = new DatagramPacket(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地址和端口。
Java使用DatagramSocket的更多相关文章
- java之DatagramSocket、DatagramPackage丶MulticastSocket 广播学习
1.基本概念: a.DatagramPacket与DatagramSocket位于java.net包中 b.DatagramPacket表示存放数据的数据报,DatagramSocket表示接受或发送 ...
- Java Socket, DatagramSocket, ServerSocketChannel io代码跟踪
Java Socket, DatagramSocket, ServerSocketChannel这三个分别对应了,TCP, udp, NIO通信API封装.JDK封装了,想跟下代码,看下具体最后是怎么 ...
- 关于android socket出现at java.net.DatagramSocket java.net.BindException at libcore.io.IoBridge.bind(IoBridge.java:89)等waring
经查,是socket地址重复使用的原因,将代码做如下改变即可. ctlClient = new DatagramSocket(TRANSCTLPORT); ctlClient = new Datagr ...
- java中DatagramSocket连续发送多个数据报包时产生丢包现象解决方案
try { //向指定的ip和端口发送数据~! //先说明一下数据是谁发送过来的! byte[] ip = InetAddress.getLocalHost().getHostAddress().ge ...
- java实现UDP协议传输DatagramSocket
摘自:http://blog.csdn.net/wintys/article/details/3525643/ Server端. package com.topca.server; import ja ...
- Java中的DatagramPacket与DatagramSocket的初步(转)
1.基本概念: a.DatagramPacket与DatagramSocket位于java.net包中 b.DatagramPacket表示存放数据的数据报,DatagramSocket表示接受或发送 ...
- java下udp的DatagramSocket 发送与接收
发送 package cn.stat.p4.ipdemo; import java.io.BufferedReader; import java.io.IOException; import java ...
- Java Networking: UDP DatagramSocket (翻译)
原文:http://tutorials.jenkov.com/java-networking/udp-datagram-sockets.html UDP vs. TCP Sending Data vi ...
- 试着用java实现DNS(一)——DatagramSocket, DatagramPacket, Message
一般来说,自己编写DNS是没有必要的,目前开源的dns服务软件很多,功能也很强大.但是,有时候又是很有必要的,有着诸多好处.比如说,用于企业内网,简化DNS配置,可以根据企业需求添加新的功能,非常灵活 ...
随机推荐
- 安卓中級教程(8):pathbutton中的animation.java研究(1)
src/geniuz/myPathbutton/myAnimations.java package geniuz.myPathbutton; import java.util.ArrayList; i ...
- 美萍超市销售管理系统标准版access数据库密码mp611
美萍超市销售管理系统标准版access数据库密码mp611 作者:admin 来源:本站 发表时间:2015-10-14 19:01:43 点击:199 美萍超市销售管理系统标准版access后 ...
- ios中蓝牙自动连接出现硬件提示框的问题
出现如图所示情况,这时候有两种方法可以处理,一种是让硬件部修改硬件配对,另一种是程序里面测试该提示框的对应特征值,不要调用该特征值就不会出现 //2.扫描到Characteristics,特征回调 - ...
- 安装运行Hadoop
1 准备环境 1.1 Ubuntu 或者 VMware Workstation Pro+Ubuntu 1.2 Jdk 1.3 eclipse 或其他开发工具(可选) 2 安装Hadoop 2.1 从h ...
- SQLSERVER2012 Audit (审核)功能
数据库表结构和数据有时会被无意或者恶意,或者需要追踪最近的数据结构变更记录,以往必须通过日志查询,SQL Server2008开始提供了 审核(Audit )功能,SQL2012有所升级,利用它可以实 ...
- LeetCode Logger Rate Limiter
原题链接在这里:https://leetcode.com/problems/logger-rate-limiter/ 题目: Design a logger system that receive s ...
- 第二篇:白话tornado源码之待请求阶段
上篇<白话tornado源码之一个脚本引发的血案>用上帝视角多整个框架做了一个概述,同时也看清了web框架的的本质,下面我们从tornado程序的起始来分析其源码. 概述 上图是torna ...
- C++学习笔记 知识集锦(二)
1. 命名规范 2. 代码格式 3. QString的判断 4. 对象的判空 5. 隐式接口&显式接口 6. vector&string 7. static 8. const 9. v ...
- JS中isPrototypeOf 和hasOwnProperty 的区别 ------- js使用in和hasOwnProperty获取对象属性的区别
JS中isPrototypeOf 和hasOwnProperty 的区别 1.isPrototypeOf isPrototypeOf是用来判断指定对象object1是否存在于另一个对象object2的 ...
- 当利用pip安装模块出现错误时咋办
>在DOS窗口中到Python安装路径的scripts中执行 pip install pyperclip 出现错误 >>错误提示:Fatal error in launcher: ...