`

NIO UDP 编程

    博客分类:
  • java
阅读更多
   和TCP的SocketChannel类似,UDP的DatagramChannel能充分利用NIO的优势。

服务端:Selector, DatagramChannel, ByteBuffer

客户端:DatagramChannel, ByteBuffer

区别:
a. 服务端没有与TCP的ServerSocketChannel相对应的Channel,服务端和客户端之间更趋于平等,不过服务端的端口号还是固定的。

b. Selector在处理完读取操作后,会触发写操作:发送数据到客户端。

1. 服务端
public class UDPEchoServerSelector {

	private static final int TIMEOUT = 4000; // 超时 (毫秒)
	private static final int CAPACITY = 255;

	public static void main(String[] args) throws IOException {
		args = new String[1];
		args[0] = "4451";

		int servPort = Integer.parseInt(args[0]);

		Selector sel = Selector.open(); // 创建选择器,可以处理多路通道。

		DatagramChannel channel = DatagramChannel.open();
		channel.configureBlocking(false);
		channel.socket().bind(new InetSocketAddress(servPort)); // 通道关联的socket绑定地址
		channel.register(sel, SelectionKey.OP_READ, new ClientData());

		while (true) { // 持续运行,接收和返回数据
			if (sel.select(TIMEOUT) == 0) {
				System.out.println("No I/O needs to be processed");
				continue;
			}

			Iterator<SelectionKey> iter = sel.selectedKeys().iterator(); // 获取可操作的选择键集合
			while (iter.hasNext()) {
				SelectionKey key = iter.next(); // 键为位掩码

				if (key.isReadable()) { // 客户端有数据发送过来
					handleRead(key);
				}

				if (key.isValid() && key.isWritable()) { // 通道正常,且客户端需要响应
					handleWrite(key);
				}

				iter.remove(); // 从集合中移除选择键
			}

		}
	}

	private static void handleRead(SelectionKey key) throws IOException {
		DatagramChannel channel = (DatagramChannel) key.channel();
		ClientData clntDat = (ClientData) key.attachment();
		clntDat.buffer.clear();
		clntDat.clientAddress = channel.receive(clntDat.buffer); // 获取客户端的地址,用以发送响应
		if (clntDat.clientAddress != null) { // 接收到数据
			key.interestOps(SelectionKey.OP_WRITE); // 关注客户端读取响应
		}
	}

	private static void handleWrite(SelectionKey key) throws IOException {
		DatagramChannel channel = (DatagramChannel) key.channel();
		ClientData clntDat = (ClientData) key.attachment();
		clntDat.buffer.flip(); // 从起始位置开始发送
		int bytesSent = channel.send(clntDat.buffer, clntDat.clientAddress);
		if (bytesSent != 0) {
			key.interestOps(SelectionKey.OP_READ); // 关注客户端发送数据
		}
	}

	public static class ClientData {
		public SocketAddress clientAddress;
		public ByteBuffer buffer = ByteBuffer.allocate(CAPACITY);
	}
}



2. 客户端
public class UDPEchoClient {

	private static final int CAPACITY = 255;
	private static final String UTF8 = "UTF-8";

	public static void main(String[] args) throws IOException {
		args = new String[2];
		args[0] = "localhost";
		args[1] = "4451";

		String servName = args[0];
		int servPort = Integer.parseInt(args[1]);

		DatagramChannel clntChan = DatagramChannel.open();
		clntChan.configureBlocking(false);
		clntChan.connect(new InetSocketAddress(servName, servPort));

		ByteBuffer sentBuffer = ByteBuffer.wrap("Hello UDP".getBytes(UTF8));
		int bytesSent = clntChan.write(sentBuffer); // 向服务器发送数据
		System.out.println("UDP client sent " + bytesSent + " bytes");

		ByteBuffer recvBuffer = ByteBuffer.allocate(CAPACITY);
		clntChan.receive(recvBuffer); // 读取响应
		recvBuffer.flip();
		System.out.println("UDP client received: " + new String(recvBuffer.array(), UTF8));
	}
}



客户端连接服务器后,发送数据可以用write或send方法:
...
clntChan.connect(new InetSocketAddress(servName, servPort));
...
int bytesSent = clntChan.write(sentBuffer);


...
clntChan.connect(new InetSocketAddress(servName, servPort));
...
int bytesSent = clntChan.send(sentBuffer, new InetSocketAddress(servName, servPort)); // 发送地址必须和前面的连接地址相同,否则报java.lang.IllegalArgumentException: Connected address not equal to target address


客户端没有连接服务器,需要用send方法指定目标地址:
...
int bytesSent = clntChan.send(sentBuffer, new InetSocketAddress(servName, servPort)); // 使用write方法会报java.nio.channels.NotYetConnectedException
分享到:
评论

相关推荐

    《NIO与Socket编程技术指南》高洪岩.zip

    非常详细地讲解了NIO中的缓冲区、通道、选择器、编码,以及使用Socket技术实现TCP/IP和UDP编程,细化到了演示全部SocketOption的特性,这对理解基于NIO和Socket技术为基础所开发的NIO框架是非常有好处的,本书以案例...

    Java NIO实例UDP发送接收数据代码分享

    "Java NIO实例UDP发送接收数据代码分享" Java NIO(Non-blocking I/O)是一种异步I/O模型,允许开发者在单个线程中处理多个I/O操作,从而提高程序的性能和可扩展性。在Java NIO中,DatagramChannel是专门用于发送...

    NIO编程技术指南_预览版

    在网络编程中,NIO主要应用于TCP和UDP通信。SocketChannel用于TCP,而DatagramChannel用于UDP。它们都支持非阻塞模式,可以结合Selector实现高效的网络服务器。 9. **Java NIO与NIO.2** Java NIO在Java 7中进一步...

    Java Socket编程实例(五)- NIO UDP实践

    Java Socket编程中的NIO(非阻塞I/O)在UDP通信中的应用主要涉及到高效的数据传输和并发处理。本文将深入探讨如何使用NIO与UDP结合,实现一个简单的回显服务器,即UDPEchoSelectorProtocol。 首先,我们来看一下`...

    java udp socket 网络编程

    - UDP编程中应处理各种异常,如`SocketException`、`IOException`等。 - 必要时,使用`close()`方法关闭套接字,释放系统资源。 7. **性能优化**: - UDP的高效性在于其无连接特性和快速传输,但这也可能导致丢...

    UDP NIO聊天系统

    NIO(Non-blocking I/O)是Java从1.4版本开始引入的一个新特性,它提供了一种不同于传统阻塞I/O的编程模型。在NIO中,可以同时处理多个连接,而不需要为每个连接创建单独的线程,这极大地提高了服务器的并发能力。...

    详细介绍 NIO与Netty编程-实战讲义详细pdf.7z

    **NIO(非阻塞I/O)与Netty编程**是现代Java网络应用开发中的重要技术,它们在处理高并发、低延迟的网络通信场景中起着关键作用。本讲义详细介绍了这两种技术,旨在帮助开发者更好地理解和运用它们。 ### 一、BIO...

    传统BIO编程模型及NIO编程模型源码

    Netty是一个基于NIO的高性能、异步事件驱动的网络应用程序框架,它简化了网络编程,特别是对于高并发的TCP和UDP服务。Netty使用了高级的NIO特性,如epoll和kqueue,提供了更高效的性能和更好的可扩展性。 在Netty中...

    20. 网络编程2UDP编程1.rar

    在J2ME中,我们通常使用`java.nio`或`java.net`包中的类来实现UDP通信。 首先,要创建一个UDP套接字,我们需要使用`DatagramSocket`类。这个类允许我们发送和接收数据报(datagrams),数据报是UDP通信的基本单位。...

    Java网络编程UDP

    1. **DatagramSocket**:这是Java UDP编程的主要接口,用于发送和接收数据报。创建一个`DatagramSocket`对象,你可以指定一个端口号,如果没有指定,系统会自动分配一个。一旦创建,就可以通过`send()`方法发送`...

    一站式学习Java网络编程 全面理解BIO:NIO:AIO1

    全面理解 Java 网络编程 - BIO、NIO、AIO 本课程旨在帮助学生全面理解 Java 网络编程中的 BIO、NIO、AIO 三剑客,掌握 RPC 编程的基础知识,并结合实战项目巩固所学。 一、网络编程三剑客 - BIO、NIO、AIO BIO...

    java 基础知识之网络通信(TCP通信、UDP通信、多播以及NIO)总结

    Java 基础知识之网络通信(TCP 通信、UDP 通信、多播以及 NIO) Java 基础知识之网络通信是 Java 语言中不可或缺的一部分,包括 TCP 通信、UDP 通信、多播以及 NIO 等多种形式。下面将对这些知识点进行详细的解释。...

    网络编程(socket、NIO、mina)---demo

    在这个"网络编程(socket、NIO、mina)---demo"的主题中,我们将深入探讨三个关键概念:Socket编程、非阻塞I/O(Non-blocking I/O,简称NIO)以及Apache Mina框架。这些技术广泛应用于构建高性能、高并发的网络应用...

    基于TCP和UDP的SOCKT编程源代码

    Socket编程是网络编程中的基础部分,它允许两个网络应用程序通过TCP或UDP协议进行通信。在本资源中,我们关注的是基于TCP和UDP的Socket编程,其中包含JAVA代码和C语言编写的示例。TCP(传输控制协议)提供的是面向...

    java网络编程NIO视频教程

    - **学习目标**:了解UDP协议下的NIO通信实现。 #### 11. Java NIO-Channel-分散和聚集 - **主要内容**:介绍NIO中分散读取和聚集写入的概念与实现。 - **学习目标**:掌握高效的数据传输技巧。 #### 12. Java NIO...

    NIO 入门.chm,NIO 入门.chm

    **NIO(New Input/Output)是Java编程语言中用于替代标准I/O(BIO,Blocking I/O)的一组API,它提供了非阻塞式的I/O操作方式,极大地提升了Java在处理I/O密集型应用时的性能。NIO在Java 1.4版本中被引入,之后在...

    Java NIO英文高清原版

    Netty是一个基于NIO的高性能、异步事件驱动的网络应用框架,它简化了网络编程,广泛应用于服务器端应用开发。 NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器(Selector)。以下是对这些核心概念的...

    NIO入门pdf分享

    6. **网络通信**:NIO为网络通信提供了SocketChannel和ServerSocketChannel,它们可以实现TCP和UDP的非阻塞连接。 7. **scatter/gather传输**:NIO支持scatter/gather传输,即数据可以从多个缓冲区写入通道,也可以...

    Java网络编程 NIO Netty

    Java网络编程领域中,NIO(Non-blocking Input/Output,非阻塞I/O)和Netty框架是两个关键概念。NIO是一种I/O模型,它与传统的BIO(Blocking I/O)模型不同,BIO在处理连接时一旦进行读写操作就会阻塞,直到数据传输...

Global site tag (gtag.js) - Google Analytics