初学netty打算写一点东西来熟练一下自己刚刚学的东西,这次想要实现一个能够传输一个自定义message类的传输
实现思路:
1.在客户端的编码器上实现当收到一个message时先发生message的长度随后在发送message
2.在服务器的解码器中实现先读取一个int也就是message的长度随后读取int长度的byte如果长度不够或者有问题那么就通过bytebuffer的mark和reset回到读取int之前的位置。
服务器代码如下:
public class test1 {
EventLoopGroup parentGroup = new NioEventLoopGroup();
EventLoopGroup childGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
ChannelFuture bind;
public void start(int port){
try {
bootstrap.group(parentGroup, childGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new myiniternizaied());
bind =bootstrap.bind(port).sync();
bind.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
System.err.println("启动失败");
parentGroup.shutdownGracefully();
childGroup.shutdownGracefully();
}finally {
this.stop();
}
}
public void stop(){
parentGroup.shutdownGracefully();
childGroup.shutdownGracefully();
}
public static void main(String[] args) {
test1 t = new test1();
t.start(9010);
System.out.println("sssssssssssssss");
}
}
class message implements Serializable {
public class msg0 implements Serializable{
private String message;
private Date time;
public String getMessage(){return message;}
public Date getTime(){return time;}
private msg0(String message){
this.message=message;
this.time=new Date();
}
}
private int length;
private msg0 msg0;
public int getState(){return length;}
public msg0 getMsg0(){ return msg0; }
public void setState(int state){this.length=state;}
public void setMsg0(String msg0){this.msg0=new msg0(msg0);}
public static message bytetomsg0(byte[] bytes) throws IOException, ClassNotFoundException {
message msg;
ByteArrayInputStream inputStream = null;
ObjectInputStream objectInputStream = null;
try {
inputStream = new ByteArrayInputStream(bytes);
objectInputStream = new ObjectInputStream(inputStream);
msg = (message) objectInputStream.readObject();
} finally {
objectInputStream.close();
inputStream.close();
}
return msg;
}
public static byte[] msgtobytes(message msg) {
byte[] bytes = null;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = null;
try {
objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(msg);
objectOutputStream.flush();
bytes = outputStream.toByteArray();
objectOutputStream.close();
outputStream.close();
}catch (IOException e){
e.printStackTrace();
System.err.println(e.getMessage());
}
return bytes;
}
}
class myiniternizaied extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// pipeline.addLast(new ByteArrayDecoder());
pipeline.addLast(new mydecoder());
// pipeline.addLast(new mydecoder2());
pipeline.addLast(new myhandler());
}
}
class mydecoder extends ByteToMessageDecoder{
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
// if (in.readableBytes()>=0){
// out.add(in.toString(Charset.forName("UTF-8")));
// }
in.markReaderIndex();
int length = in.readInt();
if (in.readableBytes()<length||in.readableBytes()<=0){
in.resetReaderIndex();
return;
}
byte[] bytes = new byte[length];
in.readBytes(bytes);
message message = com.caohao.jiami.learn1.nettytest.message.bytetomsg0(bytes);
out.add(message);
}
}
class mydecoder2 extends MessageToMessageDecoder<byte[]>{
@Override
protected void decode(ChannelHandlerContext ctx, byte[] msg, List<Object> out) throws Exception {
message message = com.caohao.jiami.learn1.nettytest.message.bytetomsg0(msg);
out.add(message);
}
}
class myhandler extends SimpleChannelInboundHandler<message>{
@Override
protected void channelRead0(ChannelHandlerContext ctx, message msg) throws Exception {
System.out.println("message state is "+msg.getState()+"and message is "+msg.getMsg0());
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}
客户端代码如下:
public class test1chilent {
EventLoopGroup parentGroup = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
ChannelFuture bind;
public void start(int port){
try {
bind = bootstrap.group(parentGroup)
.channel(NioSocketChannel.class)
.remoteAddress("127.0.0.1", 9010)
.handler(new handler1())
.connect().sync();
message m = new message();
m.setState(1);
m.setMsg0("你好啊,我是曹昊");
System.out.println("send begin");
bind.channel().writeAndFlush(m);
System.out.println("send finished");
bind.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
System.err.println("启动失败");
parentGroup.shutdownGracefully();
}finally {
this.stop();
}
}
public void stop(){
parentGroup.shutdownGracefully();
}
// public void sendmessage(Object s){
// Channel channel = bind.channel();
// System.out.println("readliable to send message");
// if (channel.isWritable()) {
// channel.writeAndFlush(s);
// }else
// System.err.println("无法传输数据");
// }
public static void main(String[] args) {
test1chilent t = new test1chilent();
t.start(9011);
System.out.println("ssssssssss222222");
}
class handler1 extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// pipeline.addLast(new StringEncoder(Charset.forName("GBK")));
pipeline.addLast(new messagetobyte());
}