TCP/IP學習筆記五:Netty使用–簡單通信編程1
標籤(空格分隔):Netty 網絡編程
Netty的簡單使用示例。
編程思路按照註釋進行就可以了。
一、導入Netty的jar
最先版本:netty-all-5.0.0.Alpha2.jar
二、服務器端
package com.netty.demo1.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
/**
* Netty NIO 服務器端
* @author MOTUI
*
*/
public class NettyNIOServer {
public static void main(String[] args) throws InterruptedException {
//1.創建NIOServerSocketChannel的服務引導
ServerBootstrap serverBootstrap = new ServerBootstrap();
//2.創建線程池 boss(請求轉發) worker(IO事件處理)
NioEventLoopGroup boss = new NioEventLoopGroup();
NioEventLoopGroup worker = new NioEventLoopGroup();
//3.綁定線程
serverBootstrap.group(boss, worker);
//4.設置ServerSocket服務類
serverBootstrap.channel(NioServerSocketChannel.class);
//5.綁定IO處理事件
serverBootstrap.childHandler(new ServerChannelInitializer());
//6.綁定服務端口
System.out.println("服務器監聽8989端口");
ChannelFuture future = serverBootstrap.bind(8989).sync();
//等待服務器被關閉
future.channel().closeFuture().sync();
//釋放線程資源
worker.shutdownGracefully();
boss.shutdownGracefully();
}
}
註冊IO事件處理類
package com.netty.demo1.server;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {
/**
* 註冊IO事件處理類
*/
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new ServerRequestResponseHander());
}
}
IO事件處理類
package com.netty.demo1.server;
import java.util.Date;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.CharsetUtil;
/**
* 事件處理類
* @author MOTUI
*
*/
public class ServerRequestResponseHander extends ChannelHandlerAdapter {
/**
* 異常調用
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
System.out.println("發生異常了···異常信息:"+cause.getMessage());
}
/**
* 讀數據調用
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
ByteBuf buffer=(ByteBuf) msg;
System.out.println("服務器接收到的數據:"+buffer.toString(CharsetUtil.UTF_8));
//ctx.writeAndFlush(msg);//寫回響應
//響應一個時間
ByteBuf buf=ctx.alloc().buffer(1024);
buf.writeBytes(new Date().toString().getBytes());
ctx.writeAndFlush(buf);
}
}
客戶端
package com.netty.demo1.client;
import java.net.InetSocketAddress;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
/**
* Netty NIO 客戶端
* @author MOTUI
*
*/
public class NettyNIOClient {
public static void main(String[] args) throws InterruptedException {
//1.創建NIOSocketChannel的服務引導
Bootstrap bootstrap = new Bootstrap();
//2.創建線程池 worker(IO事件處理)
NioEventLoopGroup boss = new NioEventLoopGroup();
//3.關聯線程池
bootstrap.group(boss);
//4.設置NioSocketChannel
bootstrap.channel(NioSocketChannel.class);
//5.綁定IO處理事件
bootstrap.handler(new ClientChannelInitializer());
//6.鏈接服務器
ChannelFuture future = bootstrap.connect(new InetSocketAddress("192.168.0.117", 8989));
//等待關閉連接
future.channel().closeFuture().sync();
//釋放資源
boss.shutdownGracefully();
}
}
客戶端註冊IO事件處理類
package com.netty.demo1.client;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
public class ClientChannelInitializer extends ChannelInitializer<SocketChannel> {
/**
* 註冊IO事件處理類
*/
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new ClientRequestResponseHander());
}
}
客戶端IO事件處理類
package com.netty.demo1.client;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.CharsetUtil;
/**
* 事件處理類
* @author MOTUI
*
*/
public class ClientRequestResponseHander extends ChannelHandlerAdapter {
/**
* 異常調用
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
System.out.println("發生異常了···異常信息:"+cause.getMessage());
}
/**
* 發送請求
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
//創建ByteBuf
ByteBuf buf = Unpooled.buffer(1024);
buf.writeBytes("你好,我好,大家好!".getBytes());
ctx.writeAndFlush(buf);
}
/**
* 讀數據調用
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
ByteBuf buffer=(ByteBuf) msg;
System.out.println("客戶端收到:"+buffer.toString(CharsetUtil.UTF_8));
//關閉鏈接
ctx.close();
}
}
總結:
編程思路按照官方文檔進行編碼,簡單類型的傳遞沒有太大的問題,對於對象類型數據的傳輸會存在一些問題(下篇介紹對象類型的傳輸)。