`

采用NIO实现一个Socket服务器

 
阅读更多

      以前用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();
		}
	}

}

 

分享到:
评论

相关推荐

    Android 通过Socket 和服务器通讯

    为了防止一直收数据,浪费电池的电,采用NIO的方式读socket的数据,这个是本文的关键 (3)开启一个线程,做心跳,防止socket连接终断 , SocketHeartThread (4)构建 SocketThreadManager对以上三个thread进行...

    NIO socket编程小例子 加法服务器

    使用NIO channel 实现的加法服务器 附带客户端 服务器端代码 简单易懂

    java socketNIO 实现多客户端聊天室 代码

    利用socketNIO实现的多客户端聊天室,非阻塞式IO,java代码编写,使用方法:先启动服务端代码再启动客户端代码,可启动多个客户端代码。若使用多个电脑启动客户端,需在客户端代码中更改一下ip地址。

    java NIO socket聊天室

    使用NIO socket不需要多线程来处理多个连接的请求,效率非常高 ...4,修改封装http做成短连接处理,就是一个小型的webserver,或者结合java2D和robot做远程监控 5,封装自己的协议可以做成自己需要的服务器端程序,

    java nio 通信服务器、客户端完整例子

    用java编写的nio通信的例子,nio是io编程的新版本,比io较流行。同时本例子是适用socket通信的。可以在此基础上,添加您的个人应用。本例子适用于:java通信的学习者,android平台通信的学习者。

    java nio socket 例子

    本例包含服务器端和客户端,多线程,每线程多次发送,Eclipse工程,启动服务器使用 nu.javafaq.server.NioServer,启动客户端使用 nu.javafaq.client.NioClient。另本例取自javafaq.nv上的程序修改而成

    NIO 服务器客户端例子

    这是一个用java NIO 实现的简单多线程服务器有客户端例子,仅供学习参考。

    Java使用NioSocket手动实现HTTP服务器

    本篇文章主要介绍了Java使用NioSocket手动实现HTTP服务器,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。

    常见NIO开源框架(MINA、xSocket)学习

    不过实际应用中一个socket服务器采用传统的阻塞式socket方式通信可能会是一场灾难,一路socket同时进行读写操作可能就需要两条线程,如果需要并发一百路socket(这个量其实很小了),可能就是两百条线程,大概几分钟...

    Java应用服务器Java-Nio-Services.zip

    JAVA服务器基于JAVA NIO I. 实现HTTP协议 II. 实现HTTPS协议 III. 实现FASTCGI协议(Client端) 运行HTTP/HTTPS服务器 运行开发包下jar文件 java -jar http-server-version-{version}.jar   ...

    linux socket NIO epoll教程参数讲解.zip

    大并发服务器编程模型 windows iocp完成端口模型可支持1万大并发,但是linux能作到5万大并发

    Java视频教程 Java游戏服务器端开发 Netty NIO AIO Mina视频教程

    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 ...

    Android-AndroidAsync异步SocketHTTP(客户端服务器)WebSocket和socket.io库

    异步Socket,HTTP(客户端 服务器),WebSocket,和socket.io库。基于NIO而不是线程。

    java多路复用socket客户端.

    Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道。可以通过以下2种方式创建SocketChannel: 打开一个SocketChannel并连接到互联网上的某台服务器。 一个新连接到达ServerSocketChannel时,会创建一个...

    java nio 网络编程指南

    基于java nio的服务器与客户端的开发指南

    详解Android 通过Socket 和服务器通讯(附demo)

    Android 通过Socket 和服务器...为了防止一直收数据,浪费电池的电,采用NIO的方式读socket的数据,这个是本文的关键 (3)开启一个线程,做心跳,防止socket连接终断 , SocketHeartThread  (4)构建 SocketThreadMa

    java解读NIOSocket非阻塞模式.zip

    jdk供的无阻塞I/O(NIO)有效解决了多线程服务器存在的线程开销问题,但在使用上略显得复杂一些。在NIO中使用多线程,主要目的已不是为了应对每个客户端请求而分配独立的服务线程,而是通过多线程充分使用用多个CPU...

    基于netty编写的socket服务端

    基于netty框架编写的socket服务器

    httpcore-nio-4.3.jar包

    用Java实现非阻塞通信 ,用ServerSocket和Socket来编写服务器程序和客户程序,是Java网络编程的最基本的方式。 httpcore-nio-4.3.jar包

Global site tag (gtag.js) - Google Analytics