`

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

}

 

分享到:
评论

相关推荐

    java nio 实现socket

    ### Java NIO 实现Socket通信详解 #### 一、NIO与传统IO的区别及优势 在探讨如何使用Java NIO实现Socket通信之前,我们需要先理解NIO(Non-blocking I/O,非阻塞I/O)与传统阻塞I/O之间的区别。 **传统阻塞I/O...

    使用NIO实现非阻塞socket通信

    本项目利用NIO实现了一个简单的非阻塞socket通信的聊天工具,使得在高并发环境下,服务器能够同时处理多个客户端连接,提高系统性能。 1. **非阻塞I/O**: 在BIO模型中,读写操作是阻塞的,即当没有数据可读或无法...

    Java NIO Socket基本

    在NIO中,我们不再像BIO那样等待一个操作完成,而是通过选择器(Selector)监控多个通道(Channel),从而实现多路复用。 在Java NIO中,核心组件包括以下几个: 1. **通道(Channel)**:类似于流,但支持双向...

    Socket 之 BIO、NIO、Netty 简单实现

    这种模型适合连接数量较少且固定的场景,因为当并发量增大时,服务器需要为每个连接创建一个线程,可能导致线程资源耗尽。 **3. NIO (Non-blocking I/O)** Java 1.4引入了NIO,提供了一种非阻塞的I/O模型。在NIO中...

    nio.rar_NIO_NIO-socket_java nio_java 实例_java.nio

    标题“nio.rar_NIO_NIO-socket_java nio_java 实例_java.nio”表明这个压缩包包含了一个关于Java NIO的实例,特别是关于NIO套接字(Socket)的编程示例。NIO套接字是Java NIO库中用于网络通信的关键组件,它们允许...

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

    《NIO与Socket编程技术指南》是一本深入探讨Java NIO(New Input/Output)和Socket编程的专业书籍,由高洪岩撰写。本书主要针对Java开发者,旨在帮助他们理解和掌握这两种在开发网络应用中至关重要的技术。 Java ...

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

    总结来说,"NIO socket编程小例子 加法服务器"是一个很好的学习NIO网络编程的起点。通过这个实例,我们可以了解NIO Channel、Buffer和Selector的基本用法,以及如何构建一个简单的网络通信应用。对于任何想要提升...

    java NIO socket聊天

    `Socket`在NIO中的实现是`SocketChannel`,它代表了网络上的一个连接。`ServerSocketChannel`则用于监听客户端的连接请求。通过`ServerSocketChannel`的`accept()`方法,服务器可以接收新的客户端连接,然后将其注册...

    NioSocket,包括server端和client端

    NioSocket是一个基于Java NIO(非阻塞I/O)技术实现的网络通信框架,它包含服务器端(Server)和客户端(Client)两部分。在Java编程中,NIO(New Input/Output)提供了一种不同于传统IO模型的I/O操作方式,其核心...

    android-socket-nio-master.zip

    "android-socket-nio-master.zip" 是一个关于Android中使用Socket结合NIO实现高效通信的项目,其目标是提高Socket通信的性能和处理大量并发连接的能力。 NIO(非阻塞I/O)是Java提供的一个替代传统I/O的API,主要...

    Java Socket学习---nio实现阻塞多线程通信

    这是一个典型的回显服务器,它的主要任务是接收客户端发送的数据并原封不动地返回。在NIO中,我们通常使用`Selector`来监控多个`Channel`,而不是像传统的BIO(阻塞I/O)那样为每个连接创建一个新的线程。这样可以...

    Android 通过Socket 和服务器通讯

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

    nio的socket

    10. **通道间的连接**:`Pipe`是NIO中的一种特殊通道,用于在两个线程之间创建一个单向的数据流管道,可以实现线程间的通信。 通过以上知识点的学习和实践,初学者可以更好地理解和掌握Java NIO在Socket通信中的...

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

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

    一般Socket客户端与Mina NIO Socket客户端对比示例

    本文将通过一个对比实例,探讨一般Socket客户端与Mina NIO (Non-blocking I/O) Socket客户端的差异和特点,帮助开发者理解这两种技术在实际应用中的选择。 首先,普通Socket客户端基于BIO(Blocking I/O)模型,它...

    socket通信NIO代理模式demo实例

    本实例"socket通信NIO代理模式demo"将展示如何利用NIO来构建一个高性能的代理服务器。 代理模式是一种设计模式,它允许我们创建一个代理对象来控制对原对象的访问。在NIO代理模式中,代理服务器作为客户端与目标...

    java NIO socket聊天室

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

    netty5实现的socket服务器

    在本文中,我们将深入探讨如何使用 Netty 5 实现一个 Socket 服务器,以及它在公司实际项目中的应用,特别是为 APP 提供长连接功能。 首先,我们需要了解 Socket 基础。Socket 是一种网络通信机制,它允许两个网络...

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

    在服务端,无论是Socket、NIO还是Mina,都需要创建监听套接字来接收客户端连接,并为每个连接创建一个新的套接字或通道。而在客户端,需要建立到服务器的连接,发送和接收数据。 总结来说,这个"网络编程(socket、...

Global site tag (gtag.js) - Google Analytics