본문으로 바로가기
반응형

데이터 통신에서 프로토콜은 중요한 역할을 합니다. 오늘은 ByteBuffer를 사용하여 15바이트의 헤더와 100바이트의 바디로 구성된 데이터 프로토콜을 파싱하는 방법에 대해 알아보겠습니다.

ByteBuffer 소개
Java의 NIO 패키지에 있는 ByteBuffer는 바이트 버퍼를 표현하며, 바이너리 데이터를 읽고 쓰는 데 유용합니다.

데이터 프로토콜의 구조
  Header (15 bytes)
  Type (1 byte)
  Version (1 byte)
  ID (5 bytes)
  Longitude (4 bytes)
  Latitude (4 bytes)
  Body (100 bytes)

VO 클래스

public class DataVO {
    private String type;
    private String version;
    private String id;
    private String lon;
    private String lat;

    // getters and setters 생략...

    public static class Builder {
        private String type;
        private String version;
        private String id;
        private String lon;
        private String lat;

        public Builder setType(String type) {
            this.type = type;
            return this;
        }

        public Builder setVersion(String version) {
            this.version = version;
            return this;
        }

        public Builder setId(String id) {
            this.id = id;
            return this;
        }

        public Builder setLon(String lon) {
            this.lon = lon;
            return this;
        }

        public Builder setLat(String lat) {
            this.lat = lat;
            return this;
        }

        public DataVO build() {
            return new DataVO(this);
        }
    }

    private DataVO(Builder builder) {
        this.type = builder.type;
        this.version = builder.version;
        this.id = builder.id;
        this.lon = builder.lon;
        this.lat = builder.lat;
    }
}

 

Unpack 메서드

public DataVO unpack(byte[] data) {
    ByteBuffer buffer = ByteBuffer.wrap(data);

    byte typeByte = buffer.get();
    String type = String.valueOf(typeByte & 0xFF);

    byte versionByte = buffer.get();
    String version = String.valueOf(versionByte & 0xFF);

    byte[] idBytes = new byte[5];
    buffer.get(idBytes);
    String id = new String(idBytes, StandardCharsets.UTF_8); // UTF-8로 디코딩

    int lonInt = buffer.getInt();
    String lon = String.valueOf(lonInt);

    int latInt = buffer.getInt();
    String lat = String.valueOf(latInt);

    return new DataVO.Builder()
            .setType(type)
            .setVersion(version)
            .setId(id)
            .setLon(lon)
            .setLat(lat)
            .build();
}

 

Pack 메서드

public byte[] pack(DataVO vo) {
    ByteBuffer buffer = ByteBuffer.allocate(115); // 15(header) + 100(body)

    buffer.put(Byte.parseByte(vo.getType()));
    buffer.put(Byte.parseByte(vo.getVersion()));
    buffer.put(vo.getId().getBytes(StandardCharsets.UTF_8));
    buffer.putInt(Integer.parseInt(vo.getLon()));
    buffer.putInt(Integer.parseInt(vo.getLat()));

    // 본 예제에서는 body 부분을 처리하지 않았습니다.
    // 실제 환경에서는 body에 해당하는 데이터를 ByteBuffer에 추가해야 합니다.

    return buffer.array();
}

 

결론
ByteBuffer는 바이너리 데이터의 효율적인 처리를 도와주며, get(), getInt()와 같은 메서드를 사용하여 각 데이터를 원하는 타입으로 가져올 수 있습니다. 데이터 통신에서 정의된 프로토콜에 맞게 데이터를 파싱하거나 생성할 때 이러한 기능이 매우 유용하게 사용됩니다.

 

VO클래스를 Lombok 라이브러리를 사용하여 간단하게 하면 아래와 같이 수정가능합니다

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class DataVO {
    private String type;
    private String version;
    private String id;
    private String lon;
    private String lat;
}

Lombok 라이브러리의 @Builder와 @Getter 어노테이션을 사용하면, 코드를 간결하게 작성할 수 있어 유지보수가 용이하게 됩니다. 이를 통해 프로토콜 데이터를 쉽게 파싱하고 생성할 수 있습니다.

 

 

Random Photo

반응형

'Programing > JAVA' 카테고리의 다른 글

제네릭, 그 시작은  (0) 2023.09.20
Java에서의 Set<String> 및 Map<String, ?> 자료구조  (0) 2023.09.14
리팩토링...java...  (0) 2023.08.06
테스트 주도 개발(TDD)_예제를 통한 설명  (0) 2023.07.28
setup() 메서드  (0) 2023.07.28