分别使用Java IO、NIO、Netty实现的一个Echo Server示例

分别使用Java IO、Java NIO、Netty来实现一个简单的EchoServer(即原样返回客户端的输入信息)。

Java IO

int port = 9000;
ServerSocket ss = new ServerSocket(port);
while (true) {
	final Socket socket = ss.accept();
	new Thread(new Runnable() {
		public void run() {
			while (true) {
				try {
					BufferedInputStream in = new BufferedInputStream(
							socket.getInputStream());
					byte[] buf = new byte[1024];
					int len = in.read(buf); // read message from client
					String message = new String(buf, 0, len);
					BufferedOutputStream out = new BufferedOutputStream(
							socket.getOutputStream());
					out.write(message.getBytes()); // echo to client
					out.flush();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

		}
	}).start();
}

实际效果用telnet来演示,如下所示:

$ telnet 127.0.0.1 9000
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is ‘^]‘.
hi
hi
你好
你好

java io缺点:

需要为每个客户端连接创建一个线程。

Java NIO

ServerSocketChannel ssChannel = ServerSocketChannel.open();
int port = 9001;
ssChannel.bind(new InetSocketAddress(port));
Selector selector = Selector.open();

ssChannel.configureBlocking(false);
ssChannel.register(selector, SelectionKey.OP_ACCEPT); //注册监听连接请求

while (true) {
	selector.select();//阻塞 直到某个channel注册的事件被触发
	Set<SelectionKey> keys = selector.selectedKeys();
	for (SelectionKey key : keys) {
		if (key.isAcceptable()) { //客户端连接请求
			ServerSocketChannel ssc = (ServerSocketChannel) key
					.channel();
			SocketChannel sc = ssc.accept();
			sc.configureBlocking(false);
			sc.register(selector, SelectionKey.OP_READ); //注册监听客户端输入
		}
		if(key.isReadable()){ //客户端输入
			SocketChannel sc = (SocketChannel) key.channel();
			ByteBuffer buffer = ByteBuffer.allocate(1024);
			sc.read(buffer);

			buffer.flip();
			sc.write(buffer);
		}
	}
	keys.clear();
}

优点:

事件驱动  可通过一个线程来管理多个连接(channel)

但要注意 并不是任何场景都是NIO优于IO的。

Netty

public class NettyEchoServer {
	public class EchoServerHandler extends ChannelHandlerAdapter {
		@Override
		public void channelRead(ChannelHandlerContext ctx, Object msg) { //ehco to client
			ctx.write(msg);
			ctx.flush();
		}

		@Override
		public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
			// Close the connection when an exception is raised.
			cause.printStackTrace();
			ctx.close();
		}

	}

	private int port;

	public NettyEchoServer(int port) {
		this.port = port;
	}

	public void run() throws Exception {
		EventLoopGroup bossGroup = new NioEventLoopGroup(); 
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		try {
			ServerBootstrap b = new ServerBootstrap(); 
			b.group(bossGroup, workerGroup)
					.channel(NioServerSocketChannel.class)
					.childHandler(new ChannelInitializer<SocketChannel>() { 
								@Override
								public void initChannel(SocketChannel ch)
										throws Exception {
									ch.pipeline().addLast(
											new EchoServerHandler());
								}
							}).option(ChannelOption.SO_BACKLOG, 128) 
					.childOption(ChannelOption.SO_KEEPALIVE, true); 

			// Bind and start to accept incoming connections.
			ChannelFuture f = b.bind(port).sync(); 

			// Wait until the server socket is closed.
			// In this example, this does not happen, but you can do that to gracefully shut down your server.
			f.channel().closeFuture().sync();
		} finally {
			workerGroup.shutdownGracefully();
			bossGroup.shutdownGracefully();
		}
	}

	public static void main(String[] args) throws Exception {
		int port = 9002;
		new NettyEchoServer(port).run();
	}

}

上例摘自官方文档

优点:

似乎仅需要继承ChannelHandlerAdapter, 然后覆盖相应方法即可。

参考文档:

http://en.wikipedia.org/wiki/Non-blocking_I/O_(Java)

https://today.java.net/pub/a/today/2007/02/13/architecture-of-highly-scalable-nio-server.html

http://www.javaworld.com/article/2078654/java-se/java-se-five-ways-to-maximize-java-nio-and-nio-2.html

http://netty.io/wiki/user-guide-for-5.x.html

时间: 2024-11-10 07:59:37

分别使用Java IO、NIO、Netty实现的一个Echo Server示例的相关文章

Caused by: java.io.EOFException: Can not read response from server.

1.错误描述 The last packet successfully received from the server was 76,997 milliseconds ago. The last packet sent successfully to the server was 78,995 milliseconds ago. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.ref

java.io.FileNotFoundException: /opt/apache-tomcat-7.0.57/conf/server.xml (权限不够)

1 错误描述 [email protected]:~$ cd /opt/apache-tomcat-7.0.57 [email protected]:/opt/apache-tomcat-7.0.57$ bin/startup.sh Using CATALINA_BASE: /opt/apache-tomcat-7.0.57 Using CATALINA_HOME: /opt/apache-tomcat-7.0.57 Using CATALINA_TMPDIR: /opt/apache-tomc

对java IO,NIO简单操作

对 IO,NIO的简单操作,详细看如下代码 1.InputStream,OutputStream是对字节流的操作,Reader,Writer是对字符的操作 2.对大文件的拷贝使用RandomAccessFile类和NIO 1 import java.io.*; 2 import java.nio.ByteBuffer; 3 import java.nio.channels.FileChannel; 4 5 public class IOWriteRead { 6 7 public static

11、Java IO NIO

Java IO 方式有很多种,基于不同的 IO 抽象模型和交互方式,可以进行简单区分. 传统的 java.io 包,它基于流模型实现,提供了我们最熟知的一些 IO 功能,比如 File 抽象.输入输出流等.交互方式是同步.阻塞的方式,也就是说,在读取输入流或者写入输出流时,在读.写动作完成之前,线程会一直阻塞在那里,它们之间的调用是可靠的线性顺序.java.io 包的好处是代码比较简单.直观,缺点则是 IO 效率和扩展性存在局限性,容易成为应用性能的瓶颈.很多时候,人们也把 java.net 下

Java IO NIO详细讲解

1.IO Java IO概述 2.NIO Java NIO浅析 原文地址:https://www.cnblogs.com/yixiu868/p/11396821.html

一文理解Java IO/NIO/AIO

  目录 概述 一.IO流(同步.阻塞) 二.NIO(同步.非阻塞) 三.NIO2(异步.非阻塞) 正文 概述 在我们学习Java的IO流之前,我们都要了解几个关键词 同步与异步(synchronous/asynchronous):同步是一种可靠的有序运行机制,当我们进行同步操作时,后续的任务是等待当前调用返回,才会进行下一步:而异步则相反,其他任务不需要等待当前调用返回,通常依靠事件.回调等机制来实现任务间次序关系 阻塞与非阻塞:在进行阻塞操作时,当前线程会处于阻塞状态,无法从事其他任务,只有

java IO Nio 文件拷贝工具类Files

public static void main(String[] args) throws Exception { Files.copy(Paths.get("file/text.txt"), new FileOutputStream("nio.txt")); } Files类具体使用方法详解

JAVA IO NIO

http://www.cnblogs.com/handsome1013/p/4882862.html http://www.cnblogs.com/dolphin0520/ http://www.cnblogs.com/handsome1013/p/4882862.html http://ifeve.com/java-nio-all/ http://blog.csdn.net/zhangzeyuaaa/article/details/50520458 http://blog.csdn.net/y

tomcat链接mysql时超时报错java.io.EOFException: Can not read response from server. Expected to read 4 bytes,

需要在配置文件里加上下面就ok了 <property name=”minEvictableIdleTimeMillis” value=”1800000″ /> <property name=”numTestsPerEvictionRun” value=”3″ /> <property name=”testOnBorrow” value=”true” /> <property name=”testWhileIdle” value=”true” /> <p