`
cuisuqiang
  • 浏览: 3931984 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
3feb66c0-2fb6-35ff-968a-5f5ec10ada43
Java研发技术指南
浏览量:3647310
社区版块
存档分类
最新评论

UDP编程 UDP连接对象的理解和使用

阅读更多

之前写了一个 一个简单的UDP服务端和客户端示例 ,用于入门UDP,当我实际使用时发生了一点问题!

上次使用中我也把连接对象 DatagramSocket 写成了静态的,在类的初始化时使用,可是系统中有很多地方使用,难道我要不断的创建这个类的对象吗?

 

可以这么做,当时有后果,后果就是内存溢出。

UDP是没有状态的,DatagramSocket 创建一次即可,就是开始指向某个地址的端口,而不用每次创建。

由于UDP是无状态的,在创建 DatagramSocket  对象时只是创建了一个指向网络的对象,就像你架设一个大喇叭对着某个方向,可是你并不知道这个方向到底有没有人在听

如果,即使你没有开服务端,创建连接对象并向这个地址放松数据,都是没有问题。你用喇叭向某个方向喊没人听这没有什么!可是当你需要回应时如果一直没有接到响应,超时之后就会报错!

package udp;

import java.net.*;

/**
 * @说明 UDP客户端程序,用于对服务端发送数据,并接收服务端的回应信息
 * @author cuisuqiang
 * @version 1.0
 * @since cuisuqiang@163.com
 */
public class UdpClientSocket {
	/**
	 * 连接对象
	 */
	private static DatagramSocket ds = null;
	/**
	 * 地址对象
	 */
	private static SocketAddress address = null;
	
	/**
	 * 测试客户端发包和接收回应信息的方法
	 */
	public static void main(String[] args) throws Exception {
		init();
		while(true){
			UdpClientSocket.send(address,"你好,亲爱的!".getBytes());
			UdpClientSocket.receive();
			try {
				Thread.sleep(3 * 1000);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 对连接和地址初始化
	 */
	public static void init(){
		try {
			ds = new DatagramSocket(8899); // 邦定本地端口作为客户端
			ds.setSoTimeout(2 * 1000);
			address = new InetSocketAddress("127.0.0.1",3344);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 向指定的服务端发送数据信息
	 */
	public static void send(SocketAddress address,byte[] bytes){
		try {
			DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address);
			ds.send(dp);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 接收从指定的服务端发回的数据
	 */
	public static void receive(){
		try {
			byte[] buffer = new byte[1024];
			DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
			ds.receive(dp);		
			byte[] data = new byte[dp.getLength()];
			System.arraycopy(dp.getData(), 0, data, 0, dp.getLength());	
			System.out.println("服务端回应数据:" + new String(data));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

执行以代码运行结果如下:

java.net.SocketTimeoutException: Receive timed out
	at java.net.PlainDatagramSocketImpl.receive0(Native Method)
	at java.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.java:136)
	at java.net.DatagramSocket.receive(DatagramSocket.java:712)
	at udp.UdpClientSocket.receive(UdpClientSocket.java:69)
	at udp.UdpClientSocket.main(UdpClientSocket.java:28)

 

运行超时,但是报错的地方不是创建对象和发送数据,而是接收数据时超时!

 

这个程序一直运行,我们来搞一个服务端:

package udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;

/**
 * @说明 UDP服务类
 * @author cuisuqiang
 * @version 1.0
 * @since cuisuqiang@163.com
 */
public class UdpServerSocket {
	
	private static DatagramSocket ds = null;
	private static SocketAddress address = null;
	
	/**
	 * 测试方法
	 */
	public static void main(String[] args) throws Exception {
		init();
		System.out.println("---->服务开始监听!<----");
		while (true) {
			UdpServerSocket.receive();
			UdpServerSocket.response(address,"你好,吃了吗!");
		}		
	}
	
	public static void init(){
		try {
			ds = new DatagramSocket(3344);
			ds.setSoTimeout(0);
			address = new InetSocketAddress("127.0.0.1",8899);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 接收数据包,该方法会造成线程阻塞
	 */
	public static void receive() {
		try {
			byte[] buffer = new byte[1024];
			DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
			ds.receive(packet);
			String info = new String(packet.getData(), 0, packet.getLength());
			System.out.println("接收信息:" + info);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 将响应包发送给请求端
	 */
	public static void response(SocketAddress address,String info){
		try {
			DatagramPacket dp = new DatagramPacket(info.getBytes(), info.getBytes().length, address);
			dp.setData(info.getBytes());
			ds.send(dp);
		} catch (Exception e) {
			e.printStackTrace();
		}		
	}
}

 

运行后客户端可以正常发送和接收数据!

 

如果在实际运用中,我是设置一个系统启动项,来初始化 init 连接对象和地址,具体使用时进行异常捕获就可以了! 

 

如果你的连接对象每次创建,且使用频繁,一般几分钟系统即可搞挂!

 

请您到ITEYE看我的原创:http://cuisuqiang.iteye.com

或支持我的个人博客,地址:http://www.javacui.com

 

分享到:
评论

相关推荐

    Delphi深度编程技术

    8.1.1 TCP、UDP和IP协议 8.1.2 套接字(Socket) 8.1.3 客户/服务器模式 8.1.4 面向连接的协议套接字的调用 8.1.5 面向无连接协议的套接字的调用 8.2 利用Winsock API实现Socket编程 8.2.1 常用WinSockAPI函数 ...

    java编程实践与程序举例

    P2P网络通信、制作图像切换特效等)和编程技巧(如动态类载入、UDP多点传送、数据库连接池、网络文件下载及上传系统、邮件群发、带滚动条图像的缩放等),所有实例均来自实际项目并调试通过,并对其中的关键技术进行...

    《Delphi 深度编程及其项目应用开发》PDF书及代码

    7.2.1 多层应用系统的结构 7.2.2 存取数据的运作原理 7.2.3 更新数据的运作原理 7.3 容错处理和负载平衡 7.4 Active Form 第8章 Socket编程 8.1 WinSock基础 8.1.1 TCP、UDP和IP协议 8.1.2 套接字(Socket) 8.1.3 ...

    疯狂JAVA讲义

    5.1.2 对象的产生和使用 110 5.1.3 对象、引用和指针 111 5.1.4 对象的this引用 112 5.2 方法详解 116 5.2.1 方法的所属性 116 5.2.2 方法的参数传递机制 116 5.2.3 形参长度可变的方法 120 5.2.4 递归方法 ...

    SuperCollider-3.11.0-macOS-signed.zip 亲测可用:用于音频合成和算法合成的平台

    用于代码共享交互式编程和实时编码服务器-scsynth高质量,准确,高效的音频引擎完全可调的采样率(192k)和块大小32位浮点信号链采样缓冲区使用64位浮点快速和流畅的控制速率调制通过开放声音控制进行通信-TCP / UDP...

    TCP_IP详解卷1

    11.9 UDP和ARP之间的交互作用 118 11.10 最大UDP数据报长度 119 11.11 ICMP源站抑制差错 120 11.12 UDP服务器的设计 122 11.12.1 客户IP地址及端口号 122 11.12.2 目标IP地址 122 11.12.3 UDP输入队列 122 11.12.4 ...

    JAVA基础课程讲义

    对象的创建和使用 60 构造器(或者叫做构造方法,constructor) 60 垃圾回收机制(Garbage Collection) 63 方法的重载(overload),构造方法的重载 63 this关键字 65 static 关键字 66 静态初始化块(经常用来初始化类,...

    java源码包---java 源码 大量 实例

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    Java2实用教程.rar

    第4章类 对象和接口 4 1编程语言的几个发展阶段 4 1 1机器语言 4 1 2过程语言 4 1 3面向对象编程 4 2类 4 2 1类声明 4 2 2类体 4 2 3成员变量和局部变量 4 2 4方法 4 2 5方法重载 4 2 6构造方法 4 2 7类方法和实例...

    基于Java的视频会议系统(软件程序+WORD论文文档).zip

    在Java中Socket可以理解为客户端或者服务器端的一个特殊的对象,这个对象有两个关键的方法,一个是getInputStream方法,另一个是getOutputStream方法。getInputStream方法可以得到一个输入流,客户端的Socket对象上...

    java源码包2

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    TCPIP详解卷[1].part04

    11.9 UDP和ARP之间的交互作用 118 11.10 最大UDP数据报长度 119 11.11 ICMP源站抑制差错 120 11.12 UDP服务器的设计 122 11.12.1 客户IP地址及端口号 122 11.12.2 目标IP地址 122 11.12.3 UDP输入队列 122 11.12.4 ...

    TCPIP详解卷[1].part09

    11.9 UDP和ARP之间的交互作用 118 11.10 最大UDP数据报长度 119 11.11 ICMP源站抑制差错 120 11.12 UDP服务器的设计 122 11.12.1 客户IP地址及端口号 122 11.12.2 目标IP地址 122 11.12.3 UDP输入队列 122 11.12.4 ...

    TCPIP详解卷[1].part03

    11.9 UDP和ARP之间的交互作用 118 11.10 最大UDP数据报长度 119 11.11 ICMP源站抑制差错 120 11.12 UDP服务器的设计 122 11.12.1 客户IP地址及端口号 122 11.12.2 目标IP地址 122 11.12.3 UDP输入队列 122 11.12.4 ...

    TCPIP详解卷[1].part05

    11.9 UDP和ARP之间的交互作用 118 11.10 最大UDP数据报长度 119 11.11 ICMP源站抑制差错 120 11.12 UDP服务器的设计 122 11.12.1 客户IP地址及端口号 122 11.12.2 目标IP地址 122 11.12.3 UDP输入队列 122 11.12.4 ...

Global site tag (gtag.js) - Google Analytics