java netty 服务端向客户端发送16进制数据,客户端无法接收-已解决

项目中需要通过netty与C语言建立连接,双方是通过16进制进行数据传输


本案例主要介绍如何在JavaNetty与C#Sokcet进行字符串通信,Java服务端,C#客户端。

重点提示:网络通信中都是byte字节,两边通信一定要统一编码,尽量避免乱码与接收不到的问题。

1.设置ChildChannelInitializer.java中initChannel(SocketChannel ch)

public class ChildChannelInitializer extends ChannelInitializer<SocketChannel> {
	@Override
	protected void initChannel(SocketChannel ch) throws Exception {
		System.out.println("==================netty报告==================");
		System.out.println("信息:有一客户端链接到本服务端");
		System.out.println("IP:" + ch.localAddress().getHostName());
		System.out.println("Port:" + ch.localAddress().getPort());
		System.out.println("==================netty报告完毕==================");
		
		ChannelPipeline  pipeline  =  ch.pipeline();
		// 在管道中添加我们自己的接收数据实现方法
		/*pipeline.addLast(new MsgEncoder());
		pipeline.addLast(new MsgDecoder());*/
		//注意 我这里并没有设置管道的编码/解码
		
		pipeline.addLast("handler", serverHandler);
	}
	...
}


2.在ServerHandler.java中接收C语言客户端发来的16进制字符串

public class ServerHandler extends ChannelHandlerAdapter{

	public void channelRead(ChannelHandlerContext channel, Object msg) throws Exception {
		try {
			ByteBuf buf = (ByteBuf)msg;
			byte [] bytes = new byte[buf.readableBytes()];
			buf.readBytes(bytes);//复制内容到字节数组bytes 
			String receiveStr = ConvertCode.receiveHexToString(bytes);//将接收到的数据转为字符串,此字符串就是客户端发送的字符串
			//返回16进制到客户端
			writeToClient(receiveStr,channel,"测试");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			log.error("异常:",e);
		}
	}
	/**
	 * 公用回写数据到客户端的方法
	 * @param 需要回写的字符串
	 * @param channel
	 * @param mark 用于打印/log的输出
	 * <br>//channel.writeAndFlush(msg);//不行
	 * <br>//channel.writeAndFlush(receiveStr.getBytes());//不行
	 * <br>在netty里,进出的都是ByteBuf,楼主应确定服务端是否有对应的编码器,将字符串转化为ByteBuf
	 */
	private void writeToClient(final String receiveStr, ChannelHandlerContext channel, final String mark) {
		try {
			ByteBuf bufff = Unpooled.buffer();//netty需要用ByteBuf传输
			bufff.writeBytes(ConvertCode.hexString2Bytes(receiveStr));//对接需要16进制
			channel.writeAndFlush(bufff).addListener(new ChannelFutureListener() {
			    @Override
			    public void operationComplete(ChannelFuture future) throws Exception {
			    	StringBuilder sb = new StringBuilder("");
			    	if(!StringUtils.isEmpty(mark)){
			    		sb.append("【").append(mark).append("】");
			    	}
			        if (future.isSuccess()) {
			            	System.out.println(sb.toString()+"回写成功"+receiveStr);
			            	log.info(sb.toString()+"回写成功"+receiveStr);
			        } else {
			        	System.out.println(sb.toString()+"回写失败"+receiveStr);
			        	log.error(sb.toString()+"回写失败"+receiveStr);
			        }
			    }
			});
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("调用通用writeToClient()异常"+e.getMessage());
			log.error("调用通用writeToClient()异常:",e);
		}
	}
	
	...
}	

3.编写ConvertCode.java:在第2里面用到了ConvertCode.receiveHexToString(bytes)和ConvertCode.hexString2Bytes(receiveStr)

public class ConvertCode {
	 /**
     *  Convert byte[] to hex string.这里我们可以将byte转换成int
	 * @param src byte[] data   
	 * @return hex string   
	 */   
    public static String bytes2Str(byte[] src){   
        StringBuilder stringBuilder = new StringBuilder("");   
        if (src == null || src.length <= 0) {   
            return null;   
        }   
        for (int i = 0; i < src.length; i++) {   
            int v = src[i] & 0xFF;   
            String hv = Integer.toHexString(v);   
            if (hv.length() < 2) {   
                stringBuilder.append(0);   
            }   
            stringBuilder.append(hv);   
        }   
        return stringBuilder.toString();   
    }
    /**
 	 * @param msg
 	 * @return 接收字节数据并转为16进制字符串
 	 */
 	public static String receiveHexToString(byte[] by) {
 		try {
 			/*io.netty.buffer.WrappedByteBuf buf = (WrappedByteBuf)msg;
 			ByteBufInputStream is = new ByteBufInputStream(buf);
 			byte[] by = input2byte(is);*/
 			String str = bytes2Str(by);
 			str = str.toLowerCase();
 			return str;
 		} catch (Exception ex) {
 			ex.printStackTrace();
 			System.out.println("接收字节数据并转为16进制字符串异常");
 		}
 		return null;
 	}
}


客户端测试工具我使用的:TCPUDP Socket调试工具 V2.3 绿色免费版

猜你喜欢

转载自blog.csdn.net/yqwang75457/article/details/73913572