一个简单的聊天部分,网络上的一堆东东,有完整的不完整的,留一手的太多,还是自己写一个完整的,留自己用就好了
设计目的:
时间基本的消息为
|消息长度(4个字节)|cmd(short)|消息体|
的消息通讯方式
package com.codec;
public class NetMsg {
private short cmd;
private byte[] data;
public NetMsg(){
}
public NetMsg(short cmd, byte[] data){
this.cmd = cmd;
this.data = data;
}
public short getCmd() {
return cmd;
}
public void setCmd(short cmd) {
this.cmd = cmd;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
}
package com.codec;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
public class MsgEncode extends MessageToByteEncoder<NetMsg> {
@Override
protected void encode(ChannelHandlerContext ctx, NetMsg m, ByteBuf out) throws Exception {
int body = 0;
if (m.getData() != null){
body = m.getData().length;
}
int total = 2 + body;
out.writeInt(total);
out.writeShort(m.getCmd());
if (m.getData() != null){
out.writeBytes(m.getData());
}
}
}
package com.codec;
import java.util.List;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
public class MsgDecode extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
while(true){
if (in.readableBytes() < 4)
return;
in.markReaderIndex();
int total = in.readInt();
if (in.readableBytes() < total){
in.resetReaderIndex();
return;
}
short cmd = in.readShort();
byte[] data = new byte[total - 2];
in.readBytes(data);
NetMsg m = new NetMsg();
m.setCmd(cmd);
m.setData(data);
out.add(m);
}
}
}
package com;
import com.codec.NetMsg;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class ClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
NetMsg m = (NetMsg)msg;
System.out.println("==============from server===========");
System.out.println(new String(m.getData(), "UTF-8"));
super.channelRead(ctx, msg);
}
}
package com;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import com.codec.MsgDecode;
import com.codec.MsgEncode;
import com.codec.NetMsg;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
public class Client {
class ClientInitianlizer extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pp = ch.pipeline();
pp.addLast("decoder", new MsgDecode());
pp.addLast("encoder", new MsgEncode());
pp.addLast("handler", new ClientHandler());
}
}
public void start(String host, int port) throws InterruptedException, IOException{
System.out.println("==========>>start client host:" + host + ":" + port + "============");
EventLoopGroup group = new NioEventLoopGroup();
try{
Bootstrap b = new Bootstrap();
b.group(group);
b.channel(NioSocketChannel.class);
b.handler(new ClientInitianlizer());
Channel ch = b.connect(host, port).sync().channel();
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while(true){
String line = in.readLine();
if (line == null){
continue;
}
if (line.contains("quit")){
break;
}
NetMsg m = new NetMsg();
m.setCmd((short)100);
m.setData(line.getBytes());
ch.writeAndFlush(m);
}
}finally{
group.shutdownGracefully();
}
}
public static void main(String[] args) {
try {
new Client().start("127.0.0.1", 9001);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com;
import com.codec.NetMsg;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class ServerHandler extends ChannelInboundHandlerAdapter{
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelInactive(ctx);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
super.channelRead(ctx, msg);
NetMsg m = (NetMsg)msg;
System.out.println("==========from client==========");
System.out.println(new String(m.getData(), "UTF-8"));
ctx.writeAndFlush(msg);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
super.exceptionCaught(ctx, cause);
}
}
package com;
import com.codec.MsgDecode;
import com.codec.MsgEncode;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class Server {
class ServerInitializer extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pp = ch.pipeline();
pp.addLast("decoder", new MsgDecode());
pp.addLast("encoder", new MsgEncode());
pp.addLast("handler", new ServerHandler());
}
}
public void start(int port) throws InterruptedException {
System.out.println("===============start server port:" + port + "=====================");
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup);
b.channel(NioServerSocketChannel.class);
b.childHandler(new ServerInitializer());
ChannelFuture f = b.bind(port).sync();
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args) {
try {
new Server().start(9001);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
上面完整的代码,编译测试通过