TCP-IP學習筆記五:Netty使用--簡單通訊程式設計1
阿新 • • 發佈:2019-01-08
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();
}
}
總結:
程式設計思路按照官方文件進行編碼,簡單型別的傳遞沒有太大的問題,對於物件型別資料的傳輸會存在一些問題(下篇介紹物件型別的傳輸)。