netty Demo
今天寫了一個helloworld版本的netty程序,跟大家分享一下:
首先需要的包是:netty-all-4.1.25.Final.jar
客戶端:
StrClient.java
package client;
import java.net.InetSocketAddress;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ChannelFactory;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
?
/**
*1. 搞一個Bootstrop 對象
*
*2. 封裝Bootstrop 對象
*
*3. 寫Handler類 也就是所有的業務邏輯
*
* @author zx
*
*/
public class StrClient {
//分配一個ip和端口號
private String host;
private int port;
private NioEventLoopGroup nioEventLoopGroup;
public StrClient(String host, int port) {
this.host = host;
this.port = port;
}
//啟動項目 ip地址是 本地 端口號是888
public static void main(String[] args) throws InterruptedException {
new StrClient("localhost", 888).start();
}
public void start() throws InterruptedException {
try {
//客戶端的引導類,啟動網絡客戶端 Bootstrap有很多客戶端的屬性
Bootstrap bootstrap = new Bootstrap();
//可以理解成是一個線程池,用這個線程池來處理連接和接收數據
nioEventLoopGroup = new NioEventLoopGroup();
bootstrap.group(nioEventLoopGroup) //多線程處理,注冊一下這個組
.channel(NioSocketChannel.class) //制定通道類型是NioSocketChannel
.remoteAddress(new InetSocketAddress(host, port)) //注冊遠程服務器的地址
.handler(new ChannelInitializer<SocketChannel>() {
//↑模板代碼/
@Override
protected void initChannel(SocketChannel ch) throws Exception {
//業務邏輯
ch.pipeline().addLast(new StrClientHandler());
}
//↓模板代碼/
});
//開始連接服務器
ChannelFuture channelFuture = bootstrap.connect().sync(); //等到連接成功,否則一直阻塞線程
channelFuture.channel().closeFuture().sync(); //接收數據之后阻塞
} catch (Exception e) {
e.printStackTrace();
} finally {
nioEventLoopGroup.shutdownGracefully().sync();
}
}
}
StrClientHandler.java
package client;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
public class StrClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
//客戶端連接服務器后會調用 這里面可以發送請求
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("client -> 開始連接服務器發送數據...");
byte[] bytes = "get current time".getBytes();
ByteBuf buffer = Unpooled.buffer(bytes.length); //構造一個數組存數據
buffer.writeBytes(bytes); //給buffer寫數據 在數組里面寫入的數據
ctx.writeAndFlush(buffer); //將這個信息交給上下文 進入pipline 如果有第二個Handler也會把這個數據給這第二個Handler
}
//從服務器端接到數據之后
@Override
protected void channelRead0(ChannelHandlerContext ch, ByteBuf msg) throws Exception {
System.out.println("client -> 讀取服務器返回的對象...");
//反序列化
byte [] bytes = new byte [msg.readableBytes()]; //將這個2進制的數據寫入數組里
msg.readBytes(bytes); //實際上是寫入數組中
String messageBody = new String (bytes,"UTF-8");
System.out.println("client -> 接到數據,內容是: " + messageBody);
}
//發生異常的時候會調用
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//打印出錯的原因
cause.printStackTrace();
//發生異常的時候就會關閉這個上下文,中斷數據的傳輸
ctx.close();
}
}
?
服務端:
StrServer.java
?
package server;
?
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
?
public class StrServer {
private int port;
private NioEventLoopGroup nioEventLoopGroup;
?
public StrServer(int port) {
this.port = port;
}
?
public static void main(String[] args) throws InterruptedException {
new StrServer(888).start();
}
?
private void start() throws InterruptedException {
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
nioEventLoopGroup = new NioEventLoopGroup();
serverBootstrap.group(nioEventLoopGroup)
.channel(NioServerSocketChannel.class)
.localAddress("localhost", port)
.childHandler(new ChannelInitializer<Channel>() {
//業務邏輯
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new StrServerHandler());
}
});
ChannelFuture channelFuture = serverBootstrap.bind().sync();
System.out.println("Server -> 服務啟動成功 監聽端口, " + port);
channelFuture.channel().closeFuture().sync();
}catch (Exception e) {
e.printStackTrace();
} finally {
nioEventLoopGroup.shutdownGracefully().sync();
}
}
}
StrServerHandler.java
package server;
import java.util.Date;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class StrServerHandler extends ChannelInboundHandlerAdapter {
/**
*
*@param ctx 上下文
*@param msg 傳來的具體的數據
*
*/
//讀取客戶端發來的數據 這個方法會被調起,在服務器讀取數據的時候
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("Server -> 接到數據,開始處理...");
ByteBuf buf = (ByteBuf)msg; //將傳過來的ByteBuf強制轉換
byte [] req = new byte[buf.readableBytes()]; //2進制數組
buf.readBytes(req); //將req的內容寫到buf中
//反序列化
String requestbody = new String (req, "UTF-8");
System.out.println("Server -> 客戶端請求數據是: " + requestbody);
System.out.println("Server -> 開始寫回數據");
String currentTime = new Date().toString();
//封裝了數據的輸出
ByteBuf copiedBuffer = Unpooled.copiedBuffer(currentTime.getBytes());
ctx.write(copiedBuffer);
}
//數據讀取完成會調起
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
//發生異常會被調用
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
cause.printStackTrace();
}
}
運行服務端和客戶端的main即可啟動服務,
1. 服務端準備接受客戶端的請求信息;
2. 客戶端請求: get currentTime?
3. 服務端獲取到請求信息:get currentTime
4. 服務端準備返回數據: String responseBody = new Date() . toString();
5. 服務端返回數據
6. 客戶端獲取服務端返回的數據
?
轉載于:https://www.cnblogs.com/zx947240023/p/9178843.html
新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!總結
以上是生活随笔為你收集整理的netty Demo的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Kylin, Mondrian, Sai
- 下一篇: 第七章课后习题