실제 전투 시리즈의 안드로이드 응용 프로그램 개발의 Netty (2 개) --- 엔코더 | 디코더 | 사용 처리기

기사 읽기 것은 첫 번째 챕터의 시작 부분에서 찾고 다시 제안

기사의이 시리즈

A, 인코더 역할

인코딩 된 데이터는 원하는 데이터 포맷으로 전송하고 전송 될

둘째, 디코더의 역할

데이터 프로토콜에 따라 수신 된 데이터를 디코딩하고 처리

세, 핸들러의 역할

디코딩 된 데이터는 잘 처리

넷째, 전송과는 간단한 예에 따라 데이터를 수신

  • 전송 된 패킷 형식의 정의
바오 터우 명령 단어 데이터 길이 데이터 영역 트레일러
0x2A 바이트 바이트 데이터 문자열 0x2A
  • 상기 정의 된 패킷은, 대응하는 데이터 엔티티 클래스를 생성 할 수 있으며, 다음과 같다 :
  • 데이터 엔티티 클래스
public class PkgDataBean {
    //命令字
    private byte cmd;
    //数据长度
    private byte dataLength;
    //数据
    private String data;
	
	//省略get/set函数
}
  • 클라이언트 데이터를 직접 전송 쓸 수 PkgDataBean개체하고 ClientEncoder인코딩
  • 데이터 보내기
//获取与服务端的连接通道
Channel channel = NettyClient.getChannel();
PkgDataBean bean = new PkgDataBean();
bean.setCmd((byte) 0x01);
bean.setData(etContent.getText().toString());
bean.setDataLength((byte) bean.getData().getBytes().length);
//写入数据
channel.writeAndFlush(bean);
  • 데이터를 인코딩하는 목적은 바이트 어레이로 이송 될 것이다. 우리가 직접 엔티티 클래스의 일반적인 정의를 사용된다는 점에주의 할 수있다
public class ClientEncoder extends MessageToByteEncoder<PkgDataBean> {

    private static final String TAG = "ClientEncoder";

    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, PkgDataBean data, ByteBuf byteBuf) throws Exception {
        //根据数据包协议,生成byte数组
        byte[] bytes = {0x2A, data.getCmd(), data.getDataLength()};
        byte[] dataBytes = data.getData().getBytes();
        //将所有数据合并成一个byte数组
        byte[] all = ByteUtil.byteMergerAll(bytes, dataBytes, new byte[]{0x2A});

        //发送数据
        byteBuf.writeBytes(all);
    }
}
  • 다음과 같이 프로그램의 구현의 효과는 다음과 같습니다
    그림 삽입 설명 여기

다섯째는, 클라이언트는 우리가 사용하는 데이터 전송 Encoder인코딩에를, 서버의 정보는 다음의 제품에 이러한 데이터가 필요받을 Decoder정확한 데이터를 얻을 수 있도록, 디코딩을

  • 서버 디코더 구현, 디코딩 된 데이터를 생성 PkgDataBean엔티티
public class ServerDecoder extends ByteToMessageDecoder {
    private static final String TAG = "ServerDecoder";

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        int length = byteBuf.readableBytes();
        //收到的数据包
        byte[] data = byteBuf.readBytes(length).array();
        //判断数据包是不是一个正确的数据包
        if (data[0] == 0x2A && data[0] == data[data.length - 1]) {
            PkgDataBean bean = new PkgDataBean();
            bean.setCmd(data[1]);
            bean.setDataLength(data[2]);
            byte[] bytes = Arrays.copyOfRange(data, 3, 3 + bean.getDataLength());
            bean.setData(new String(bytes));
            Log.d(TAG, "收到了客户端发送的数据:" + bean.toString());
        }
    }
}

  • 실행 효과
    그림 삽입 설명 여기

여섯째는, 클라이언트에 대한 모든 우리의 이야기가 데이터를 전송 위, 서버는 데이터를 수신, 양 당사자의 실제 개발은 양측이있을 것이다, 그래서 데이터 전송 및 수신을 확신 Encoder, Decoder코덱 사용이 동일 여기에 복잡 정교하지 않습니다

세븐, 디코더에서 우리는 데이터가 나온 구문 분석, 당신은에서 서비스를 사용할 필요가;에서, 그 Handler핸들러는 우리의 데이터가 재 연결, 심장 박동, 클라이언트 등의 오프라인을 포함하여, 센터를 처리 있다고 할 수 있도록 프로세스 등 ... (이 기사의 뒷부분에서 언급 될 것이다)

  • 첫 번째 방법은 여러 집중 소개

    • channelRead0 () -> 때 콜백 수신 데이터
    • channelActive () - 이상> 콜백 클라이언트 연결
    • channelInactive은 () -> 콜백 클라이언트 연결이 끊어 연결이
    • () userEventTriggered -> 유휴 콜백 이벤트
    • exceptionCaught () - 콜백 이상> 출현
  • 그 위에 전달하는 경우 데이터 핸들러는? 에서 이것은 물론입니다 Decoder위쪽 오는만큼 다음과 같습니다 :

@Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
    int length = byteBuf.readableBytes();
    //收到的数据包
    byte[] data = byteBuf.readBytes(length).array();
    //判断数据包是不是一个正确的数据包
    if (data[0] == 0x2A && data[0] == data[data.length - 1]) {
        PkgDataBean bean = new PkgDataBean();
        bean.setCmd(data[1]);
        bean.setDataLength(data[2]);
        byte[] bytes = Arrays.copyOfRange(data, 3, 3 + bean.getDataLength());
        bean.setData(new String(bytes));
        Log.d(TAG, "收到了客户端发送的数据:" + bean.toString());
        //将数据传递给下一个Handler,也就是在NettyServer给ChannelPipeline添加的处理器
        list.add(bean);
    }
}
  • 데이터 분석을 사용하는 것은 ()에는 list.add 완료되면, 데이터 핸들러에 전달된다
  • Handler다음과 같이 코드는 다음과 같습니다
public class ServerHandler extends SimpleChannelInboundHandler<PkgDataBean> {

    private static final String TAG = "ServerHandler";

    /**
     * 当收到数据的回调
     *
     * @param channelHandlerContext 封装的连接对像
     * @param bean
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, PkgDataBean bean) throws Exception {
        Log.d(TAG, "收到了解码器处理过的数据:" + bean.toString());
    }
}
  • 실행 효과
    그림 삽입 설명 여기
  • 여기에 또한 일반한다 , 그렇지 않으면 잘못 것, 이것이에는 list.add () 지정된 제네릭 형식 디코더와 일치해야 함을주의!

여덟, 다음 기사가 재 연결에 초점을 맞출 것이다, 하트 비트 프로세스가 설명을 설명하기

데모는이 시리즈의 네 번째 기사에서 주어질 것이다

게시 된 140 개 원래 기사 · 원 찬양 546 · 전망 540 000 +

추천

출처blog.csdn.net/a_zhon/article/details/100831777