1.未使用 Netty 的阻塞网络编程
package com.nettyTest4;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
//1.未使用 Netty 的阻塞网络编程
public class PlainOioServer {
public void serve(int port) throws IOException {
final ServerSocket socket = new ServerSocket(port);
try {
for (;;) {
final Socket clientSocket = socket.accept();
System.out.println( "Accepted connection from " + clientSocket);
new Thread(new Runnable() {
@Override
public void run() {
OutputStream out;
try {
out = clientSocket.getOutputStream();
out.write("Hi!\r\n".getBytes( Charset.forName("UTF-8")));
out.flush();
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
clientSocket.close();
}catch (IOException ex) {
// ignore on close
}
}
}
}).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.未使用 Netty 的异步网络编程
package com.nettyTest4;
import java.io.IOException;
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.util.Iterator;
import java.util.Set;
//2.未使用 Netty 的异步网络编程 NIO
public class PlainNioServer {
public static void serve(int port) throws IOException{
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
ServerSocket socket = serverChannel.socket();
InetSocketAddress address = new InetSocketAddress(port);
//将服务器绑定到端口
socket.bind(address);
//打开Selector 来处理Channel
Selector selector = Selector.open();
//将ServerSocket注册到Selector以接收连接
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
final ByteBuffer msg = ByteBuffer.wrap("Hi!\r\n".getBytes());
for(;;){
try{
//等待需要处理的新事件,阻塞将一直持续到下一个传入事件
selector.select();
}catch(IOException ex){
ex.printStackTrace();
break;
}
}
//获取所有接收事件的Selection Key实例
Set<SelectionKey> readyKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = readyKeys.iterator();
while(iterator.hasNext()){
SelectionKey key = iterator.next();
iterator.remove();
try{
//检查事件是否是一个新的已经就绪可以被接受的连接
if(key.isAcceptable()){
ServerSocketChannel server = (ServerSocketChannel)key.channel();
SocketChannel client = server.accept();
client.configureBlocking(false);
//接受客户端并将它注册到选择器
client.register(selector, SelectionKey.OP_WRITE|SelectionKey.OP_READ, msg.duplicate());
System.out.println("Accepted connection from " + client);
}
//检查套接字是否已经准备好写数据
if(key.isWritable()){
SocketChannel client = (SocketChannel)key.channel();
ByteBuffer buffer = (ByteBuffer)key.attachment();
while (buffer.hasRemaining()) {
//将数据写到已经连接的客户端
if (client.write(buffer) == 0) {
break;
}
}
//关闭连接
client.close();
}
}catch(IOException es){
key.cancel();
try {
key.channel().close();
} catch (IOException cex) {
// ignore on close
}
}
}
}
public static void main(String[] args) throws IOException {
serve(8080);
}
}
3.使用 Netty 的阻塞网络处理
package com.nettyTest4;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.oio.OioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.oio.OioServerSocketChannel;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
//3.使用 Netty 的阻塞网络处理
public class NettyOioServer {
public void server(int port)throws Exception{
final ByteBuf buf = Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("Hi!\r\n", Charset.forName("UTF-8")));
EventLoopGroup group = new OioEventLoopGroup();
try{
//创建ServerBootstrap
ServerBootstrap b= new ServerBootstrap();
b.group(group)
//使用OIOEventLoopGroup 允许阻塞模式(传统的BIO)
.channel(OioServerSocketChannel.class) //该类即将被netty废弃
.localAddress(new InetSocketAddress(port))
//指定ChannelInitializer对于每个已接受的连接都调用它
.childHandler(new ChannelInitializer<SocketChannel>(){
@Override
public void initChannel(SocketChannel ch) throws Exception{
ch.pipeline().addLast(
// 添加一个ChannelInboundHandlerAdapter以拦截和处理事件
new ChannelInboundHandlerAdapter(){
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception{
ctx.writeAndFlush(buf.duplicate()).addListener(
//将消息写入客户端,并添加ChannelFutureListener 以便消息一被写完就关闭
ChannelFutureListener.CLOSE);
}
});
}
});
//绑定服务器已接受连接
ChannelFuture f = b.bind().sync();
f.channel().closeFuture().sync();
}finally{
//释放所有资源
group.shutdownGracefully().sync();
}
}
}
4.使用 Netty 的异步网络处理
package com.nettyTest4;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
//4.使用 Netty 的异步网络处理
public class NettyNioServer {
public void server(int port)throws Exception{
final ByteBuf buf =Unpooled.copiedBuffer("Hi!\r\n",
Charset.forName("UTF-8"));
//为非阻塞模式使用NioEventLoopGroup
EventLoopGroup group = new NioEventLoopGroup();
try{
//创建ServerBootstrap
ServerBootstrap b = new ServerBootstrap();
b.group(group).channel(NioServerSocketChannel.class)
.localAddress(new InetSocketAddress(port))
//指定ChannelInitializer 对于每个已接受的连接都调用它
.childHandler(new ChannelInitializer<SocketChannel>(){
@Override
public void initChannel(SocketChannel ch) throws Exception{
ch.pipeline().addLast(
//添加ChannelInboundHandlerAdapter 已接收和处理事件
new ChannelInboundHandlerAdapter(){
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception{
//将消息写到客户端,并添加ChannelFutureListener 以便消息一被写完就关闭连接
ctx.writeAndFlush(buf.duplicate()).addListener(ChannelFutureListener.CLOSE);
}
});
}
});
//绑定服务器已接受资源
ChannelFuture f = b.bind().sync();
f.channel().closeFuture().sync();
}finally{
//释放所有资源
group.shutdownGracefully().sync();
}
}
}
网友评论