以前用Socket写服务端,常用的做法是维护一个线程池,每当有客户端连入则交给一个特定的线程处理,处理完之后返回。解除了NIO之后,发现可以不用这样了。使用NIO的话,不需要像以前那样维护线程池了,一个线程就可以搞定多个客户端的请求。
于是自己就动手写了一个示例程序。
先描述一下程序:服务端采用ServerSocketChannel,使用Selector注册感兴趣的事件。
测试程序开启连个客户端,与服务器连接并传输内容。服务器接收到消息后,打印出来。 通过结果可以看出NIO的强大。他可以完全胜任这项任务。
虽然这个示例程序的结构有些丑陋,但重点在说明这个奇妙的交互过程。要想采用好的结构可以参见这篇博客:http://www.ibm.com/developerworks/cn/java/l-niosvr/#icomments
本人将本机IP硬编码到程序中了,所以大家下载源码不修改的话会运行不了。
贴出服务端和客户端的代码上来参考一下:
package com.wjy.nioServer; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.util.Iterator; import java.util.Set; public class NIOServer implements Runnable{ private Selector selector; private ServerSocketChannel sscChannel; private InetSocketAddress address; //private SocketChannel socketChannel; private static final int BSIZE=1024; public NIOServer(int port){ try { selector=Selector.open(); sscChannel=ServerSocketChannel.open(); sscChannel.configureBlocking(false); address=new InetSocketAddress(InetAddress.getLocalHost(), port); ServerSocket serverSocket=sscChannel.socket(); serverSocket.bind(address); sscChannel.register(selector, SelectionKey.OP_ACCEPT); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void run() { // TODO Auto-generated method stub while(true){ try { int num=0; num=selector.select(); if(num>0){ Set selectedKeys=selector.selectedKeys(); Iterator it=selectedKeys.iterator(); while(it.hasNext()){ SelectionKey key=(SelectionKey)it.next(); it.remove(); if((key.readyOps()&SelectionKey.OP_ACCEPT)==SelectionKey.OP_ACCEPT){ ServerSocketChannel serverSocketChannel=(ServerSocketChannel)key.channel(); SocketChannel socketChannel=serverSocketChannel.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); System.out.println("Connected. "+socketChannel.getLocalAddress()); } else if((key.readyOps()&SelectionKey.OP_READ)==SelectionKey.OP_READ){ //System.out.println("Received."); SocketChannel client=(SocketChannel)key.channel(); ByteBuffer buff=ByteBuffer.allocate(BSIZE); client.read(buff); buff.flip(); String encoding=System.getProperty("file.encoding"); System.out.println("receive: "+Charset.forName(encoding).decode(buff)); //key.cancel(); } } } } catch (Exception e) { // TODO: handle exception } } } }
package com.wjy.nioClient; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; public class NIOClient implements Runnable{ private String sendMsg; private Socket client; private DataOutputStream out; public NIOClient(int port,String sendMsg){ this.sendMsg=sendMsg; try { client=new Socket("10.13.30.160",port); client.setSoTimeout(10000); out = new DataOutputStream( (client.getOutputStream())); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void run() { // TODO Auto-generated method stub try { byte[] request = sendMsg.getBytes(); for(int i=0;i<10;i++){ System.out.println("Time: "+i); out.write(request); out.flush(); Thread.sleep(5000); } client.shutdownOutput(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
相关推荐
### Java NIO 实现Socket通信详解 #### 一、NIO与传统IO的区别及优势 在探讨如何使用Java NIO实现Socket通信之前,我们需要先理解NIO(Non-blocking I/O,非阻塞I/O)与传统阻塞I/O之间的区别。 **传统阻塞I/O...
本项目利用NIO实现了一个简单的非阻塞socket通信的聊天工具,使得在高并发环境下,服务器能够同时处理多个客户端连接,提高系统性能。 1. **非阻塞I/O**: 在BIO模型中,读写操作是阻塞的,即当没有数据可读或无法...
在NIO中,我们不再像BIO那样等待一个操作完成,而是通过选择器(Selector)监控多个通道(Channel),从而实现多路复用。 在Java NIO中,核心组件包括以下几个: 1. **通道(Channel)**:类似于流,但支持双向...
这种模型适合连接数量较少且固定的场景,因为当并发量增大时,服务器需要为每个连接创建一个线程,可能导致线程资源耗尽。 **3. NIO (Non-blocking I/O)** Java 1.4引入了NIO,提供了一种非阻塞的I/O模型。在NIO中...
标题“nio.rar_NIO_NIO-socket_java nio_java 实例_java.nio”表明这个压缩包包含了一个关于Java NIO的实例,特别是关于NIO套接字(Socket)的编程示例。NIO套接字是Java NIO库中用于网络通信的关键组件,它们允许...
《NIO与Socket编程技术指南》是一本深入探讨Java NIO(New Input/Output)和Socket编程的专业书籍,由高洪岩撰写。本书主要针对Java开发者,旨在帮助他们理解和掌握这两种在开发网络应用中至关重要的技术。 Java ...
总结来说,"NIO socket编程小例子 加法服务器"是一个很好的学习NIO网络编程的起点。通过这个实例,我们可以了解NIO Channel、Buffer和Selector的基本用法,以及如何构建一个简单的网络通信应用。对于任何想要提升...
`Socket`在NIO中的实现是`SocketChannel`,它代表了网络上的一个连接。`ServerSocketChannel`则用于监听客户端的连接请求。通过`ServerSocketChannel`的`accept()`方法,服务器可以接收新的客户端连接,然后将其注册...
NioSocket是一个基于Java NIO(非阻塞I/O)技术实现的网络通信框架,它包含服务器端(Server)和客户端(Client)两部分。在Java编程中,NIO(New Input/Output)提供了一种不同于传统IO模型的I/O操作方式,其核心...
"android-socket-nio-master.zip" 是一个关于Android中使用Socket结合NIO实现高效通信的项目,其目标是提高Socket通信的性能和处理大量并发连接的能力。 NIO(非阻塞I/O)是Java提供的一个替代传统I/O的API,主要...
这是一个典型的回显服务器,它的主要任务是接收客户端发送的数据并原封不动地返回。在NIO中,我们通常使用`Selector`来监控多个`Channel`,而不是像传统的BIO(阻塞I/O)那样为每个连接创建一个新的线程。这样可以...
为了防止一直收数据,浪费电池的电,采用NIO的方式读socket的数据,这个是本文的关键 (3)开启一个线程,做心跳,防止socket连接终断 , SocketHeartThread (4)构建 SocketThreadManager对以上三个thread进行...
10. **通道间的连接**:`Pipe`是NIO中的一种特殊通道,用于在两个线程之间创建一个单向的数据流管道,可以实现线程间的通信。 通过以上知识点的学习和实践,初学者可以更好地理解和掌握Java NIO在Socket通信中的...
利用socketNIO实现的多客户端聊天室,非阻塞式IO,java代码编写,使用方法:先启动服务端代码再启动客户端代码,可启动多个客户端代码。若使用多个电脑启动客户端,需在客户端代码中更改一下ip地址。
本文将通过一个对比实例,探讨一般Socket客户端与Mina NIO (Non-blocking I/O) Socket客户端的差异和特点,帮助开发者理解这两种技术在实际应用中的选择。 首先,普通Socket客户端基于BIO(Blocking I/O)模型,它...
本实例"socket通信NIO代理模式demo"将展示如何利用NIO来构建一个高性能的代理服务器。 代理模式是一种设计模式,它允许我们创建一个代理对象来控制对原对象的访问。在NIO代理模式中,代理服务器作为客户端与目标...
使用NIO socket不需要多线程来处理多个连接的请求,效率非常高 ...4,修改封装http做成短连接处理,就是一个小型的webserver,或者结合java2D和robot做远程监控 5,封装自己的协议可以做成自己需要的服务器端程序,
在本文中,我们将深入探讨如何使用 Netty 5 实现一个 Socket 服务器,以及它在公司实际项目中的应用,特别是为 APP 提供长连接功能。 首先,我们需要了解 Socket 基础。Socket 是一种网络通信机制,它允许两个网络...
在服务端,无论是Socket、NIO还是Mina,都需要创建监听套接字来接收客户端连接,并为每个连接创建一个新的套接字或通道。而在客户端,需要建立到服务器的连接,发送和接收数据。 总结来说,这个"网络编程(socket、...