首先,感谢每一位来关注的IT前辈,真诚希望您提出宝贵的意见。
我需要的效果:
1.客户端与服务端长连接TCP通信;
2.客户端通过自定义解码器,解析服务端返回的数据包;
3.客户端在服务端返回连接结果后,发送登录请求数据包,需要对数据自定义编码器解析;
4.因为是长连接,服务不能断,还需要发送登陆请求,以及其他验证消息。很重要。
数据包结构:
1.固定包头2字节;
2.消息体,全部为文本(ASCII码),汉字是GB2312编码。
3.固定包尾2字节;
我目前代码:
public class TCPClient {
public void connect(int port,String host)throws Exception{
//网络事件处理线程组
EventLoopGroup group=new NioEventLoopGroup();
//配置客户端启动类
Bootstrap b=new Bootstrap();
b.group(group).channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)//设置封包 使用一次 大数据的写操作,而不是多次小数据的写操作
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast("decoder",new DealMsg()); //设置自定义解码器
ch.pipeline().addLast("encoder",new MsgEncode()); //设置自定义编码器
ch.pipeline().addLast(new TCPClientHandler()); //设置客户端网络IO处理器
}
});
//连接服务器 同步等待成功
ChannelFuture f = b.connect(new InetSocketAddress(host,port));
//同步等待客户端通道关闭
// f.channel().closeFuture().sync(); //不关闭会发生阻塞
Channel channel = f.sync().channel();
Scanner scanner = new Scanner(System.in);
while(true){
System.out.println("请输入");
CarData carData = new CarData();
String line = scanner.nextLine();
carData.setBody(line);
//发送请求
channel.writeAndFlush(carData);
}
//释放线程组资源
// group.shutdownGracefully();
}
}
public class TCPClientHandler extends ChannelHandlerAdapter {
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println("通信异常!!");
cause.printStackTrace();
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("链接服务端成功!");
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("退出链接!!");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("接受服务器数据:【 "+msg);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.channel().writeAndFlush("数据读取完成!");
}
}
希望大家关注一下,我的问题,非常感谢。迫切需要解决解码编码,消息发送;
参考下:http://www.mamicode.com/info-detail-1948080.html
可以看看这个
package cn.ac.yangge.domain;
import io.netty.channel.Channel;
import java.util.HashMap;
/**
Created by yangge on 2017/11/15 0015.
*/
public class ChannelMap {
public static int channelNum=0;
private static HashMap channelHashMap=null;
public static HashMap getChannelHashMap() {
return channelHashMap;
}
public static Channel getChannelByName(String name){
if(channelHashMap==null||channelHashMap.isEmpty()){
return null;
}
return channelHashMap.get(name);
}
public static void addChannel(String name,Channel channel){
if(channelHashMap==null){
channelHashMap=new HashMap<>(100);
}
channelHashMap.put(name,channel);
channelNum++;
}
public static int removeChannelByName(String name){
if(channelHashMap.containsKey(name)){
channelHashMap.remove(name);
return 0;
}else{
return 1;
}
}
}
首先创建一个Map用来存储各个连接的Channel。
当有连接建立时,调用addChannel()方法:
ChannelMap.addChannel(name,ctx.channel());
当需要使用的时候使用getChannelByName()方法:
Channel channel=ChannelMap.getChannelByName(name);
if(channel.isActive()){
channel.writeAndFlush(byteBuf);
}else{
return 2;//不在线
}
问题解决,我自己调通了。不涉及机密情况下随后贴出代码。