728x90
반응형
Spring Integration을 이용해서 개발한 tcp server에서 아래와 같이 역직렬화 처리를 했습니다.
class TcpSerializer: AbstractPooledBufferByteArraySerializer() {
override fun doDeserialize(inputStream: InputStream?, buffer: ByteArray?): ByteArray? {
val data = inputStream?.readAllBytes()
data ?: return null
return data
}
override fun serialize(bytes: ByteArray, outputStream: OutputStream) {
outputStream.write(bytes)
}
}
InputStream의 readAllBytes 함수를 사용해서 client에서 보낸 데이터를 읽도록 처리했는데 정상적으로 읽힐때가 있고 정상적으로 읽히지 않을때가 있었습니다. client를 Socket을 사용한 테스트 코드로 했을때는 정상적으로 읽혔고 hercules 같은 프로그램을 사용했을때는 정상적으로 읽히지 않았습니다.
아래와 같이 client에서 Socket을 사용했을때는 정상처리 되었습니다.
@SpringBootTest
class TcpLocalTest {
@Test
fun forwardDataLogin() {
val socket = Socket(serverIp, serverPort)
val output = socket.getOutputStream()
output.write(generateData())
output.flush()
}
}
hercules은 TCP client 테스트를 할 수 있는 프로그램입니다. 이 프로그램을 사용해서 데이터를 보낼때는 정상적으로 데이터를 읽을 수가 없었습니다.
왜 그럴까 하고 생각해보니 readAllBytes 함수는 스트림의 끝을 만날 때까지 계속 읽는데 Socket을 이용한 테스트 코드에서는 flush 함수를 마지막에 호출하고 함수가 종료되서 stream의 끝이 나는데 프로그램을 사용한 tcp 연결은 stream의 끝이 명확하지 않아서 발생하는 이슈로 생각되었습니다.
그래서 readAllBytes 함수 대신 read() 함수와 readNBytes(n) 함수를 사용하게 수정하니 프로그램에서도 정상적으로 데이터가 읽혔습니다.
readAllBytes 함수와 read 함수의 차이는 아래와 같습니다.
inputStream.readAllBytes()
- readAllBytes() 메서드는 스트림에서 데이터를 읽고 끝에 도달할 때까지 데이터를 반환합니다.
- 이 메서드는 스트림의 끝을 만날 때까지 계속 읽기 때문에 스트림이 닫히거나 EOF(End of File)를 만나기 전까지 반환되지 않습니다.
- 따라서, TCP 소켓 스트림처럼 데이터가 지속적으로 들어오는 스트림에서는 블록될 가능성이 있습니다.
inputStream.read()
- read() 메서드는 버퍼를 사용하여 스트림에서 데이터를 읽습니다.
- 이 메서드는 지정된 크기의 버퍼만큼 읽고, 읽은 데이터의 양을 반환합니다.
- 스트림의 끝에 도달하지 않더라도 데이터를 읽고 처리할 수 있습니다.
결과적으로,
- inputStream.readAllBytes()는 스트림의 끝을 만날 때까지 블록될 수 있어 TCP 소켓 스트림과 같은 경우에 부적합합니다.
- inputStream.read()는 지정된 크기의 버퍼만큼 데이터를 읽고 즉시 반환하기 때문에, TCP 소켓 스트림에 더 적합합니다.
728x90
반응형
'개발 > spring, spring boot' 카테고리의 다른 글
Spring Boot 의존성 확인 방법 (0) | 2024.07.02 |
---|---|
[Spring integration] TCP 연결 끊김 처리, connectionId (0) | 2024.06.25 |
[JPA] MariaDB에서 PK를 날짜+sequence의 nextval의 조합으로 insert하는 방법 (0) | 2024.06.13 |
[WebSocket] [STOMP] client 테스트 방법 (0) | 2024.06.11 |
[Spring Boot] [WebSocket] Protocol 설정 방법 (0) | 2024.02.20 |