以前用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(); } } }
相关推荐
为了防止一直收数据,浪费电池的电,采用NIO的方式读socket的数据,这个是本文的关键 (3)开启一个线程,做心跳,防止socket连接终断 , SocketHeartThread (4)构建 SocketThreadManager对以上三个thread进行...
使用NIO channel 实现的加法服务器 附带客户端 服务器端代码 简单易懂
利用socketNIO实现的多客户端聊天室,非阻塞式IO,java代码编写,使用方法:先启动服务端代码再启动客户端代码,可启动多个客户端代码。若使用多个电脑启动客户端,需在客户端代码中更改一下ip地址。
使用NIO socket不需要多线程来处理多个连接的请求,效率非常高 ...4,修改封装http做成短连接处理,就是一个小型的webserver,或者结合java2D和robot做远程监控 5,封装自己的协议可以做成自己需要的服务器端程序,
用java编写的nio通信的例子,nio是io编程的新版本,比io较流行。同时本例子是适用socket通信的。可以在此基础上,添加您的个人应用。本例子适用于:java通信的学习者,android平台通信的学习者。
本例包含服务器端和客户端,多线程,每线程多次发送,Eclipse工程,启动服务器使用 nu.javafaq.server.NioServer,启动客户端使用 nu.javafaq.client.NioClient。另本例取自javafaq.nv上的程序修改而成
这是一个用java NIO 实现的简单多线程服务器有客户端例子,仅供学习参考。
本篇文章主要介绍了Java使用NioSocket手动实现HTTP服务器,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
不过实际应用中一个socket服务器采用传统的阻塞式socket方式通信可能会是一场灾难,一路socket同时进行读写操作可能就需要两条线程,如果需要并发一百路socket(这个量其实很小了),可能就是两百条线程,大概几分钟...
JAVA服务器基于JAVA NIO I. 实现HTTP协议 II. 实现HTTPS协议 III. 实现FASTCGI协议(Client端) 运行HTTP/HTTPS服务器 运行开发包下jar文件 java -jar http-server-version-{version}.jar ...
大并发服务器编程模型 windows iocp完成端口模型可支持1万大并发,但是linux能作到5万大并发
12.分析设计一个聊天室的小项目 二、java NIO,AIO编程视频教程 1、java NIO,AIO编程_01.flv 2、java NIO,AIO编程_02.flv 3、java NIO,AIO编程_03.flv 4、java NIO,AIO编程_04.flv 5、java NIO,AIO编程_05.flv ...
异步Socket,HTTP(客户端 服务器),WebSocket,和socket.io库。基于NIO而不是线程。
Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道。可以通过以下2种方式创建SocketChannel: 打开一个SocketChannel并连接到互联网上的某台服务器。 一个新连接到达ServerSocketChannel时,会创建一个...
基于java nio的服务器与客户端的开发指南
Android 通过Socket 和服务器...为了防止一直收数据,浪费电池的电,采用NIO的方式读socket的数据,这个是本文的关键 (3)开启一个线程,做心跳,防止socket连接终断 , SocketHeartThread (4)构建 SocketThreadMa
jdk供的无阻塞I/O(NIO)有效解决了多线程服务器存在的线程开销问题,但在使用上略显得复杂一些。在NIO中使用多线程,主要目的已不是为了应对每个客户端请求而分配独立的服务线程,而是通过多线程充分使用用多个CPU...
基于netty框架编写的socket服务器
用Java实现非阻塞通信 ,用ServerSocket和Socket来编写服务器程序和客户程序,是Java网络编程的最基本的方式。 httpcore-nio-4.3.jar包