2016-12-15 6 views
1

그래서 Java에서 SocketChannels을 사용하여 프로젝트의 데이터를 보내고받습니다. 프로젝트는 데이터의 ByteBuffer가 필요하지만 길이가 4 바이트 인 접미사가있는 타사와 상호 작용합니다.Java - socketchannel에서 읽기

수신 할 때 앞에서 4 바이트 길이를 해체하고 데이터를 추출해야하는 ByteBuffer가 수신됩니다. 받은 메시지는 길이가 고정되어 있지 않습니다.

public PedResponse send(ByteBuffer message) { 
     String returnString; 
     try { 

      message.flip(); 

      while (message.hasRemaining()) { 
       socketChannel.write(message); 
      } 

      ByteBuffer readBuffer = ByteBuffer.allocate(5000); 
      int bufferSize = socketChannel.read(readBuffer); 
      if (bufferSize == -1) { 
       socketChannel.close(); 
      } else { 
       readBuffer.flip(); 
      } 

      returnString = new String(deconstructMessage(readBuffer.array()), "UTF-8").trim(); 

      response = parser.parseResponse(returnString); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return response; 
    } 

private ByteBuffer constructMessage(byte[] data) { 

     // Construct a buffer where we'll put the data to send 
     ByteBuffer sendBuffer = ByteBuffer.allocate(4 + data.length); 

     // it's the default, but included for clarity 
     sendBuffer.order(ByteOrder.BIG_ENDIAN); 

     // Put the 4-byte length, then the data 
     sendBuffer.putInt(data.length); 
     sendBuffer.put(data); 

     // Extract the actual bytes from our sendBuffer 
     return sendBuffer; 
    } 

public byte[] deconstructMessage(byte[] data) { 

     byte[] filteredByteArray = Arrays.copyOfRange(data, 4, data.length - 4); 

     return filteredByteArray; 
    } 

//Currently not being used. 
private byte[] deconstructMessage(byte[] data) { 

     // Construct a buffer where we'll put the data to send 
     ByteBuffer receiveBuffer = ByteBuffer.allocate(data.length); 

     // it's the default, but included for clarity 
     receiveBuffer.order(ByteOrder.BIG_ENDIAN); 

     // Get the 4-byte length, then the data 
     receiveBuffer.getInt(data.length); 
     receiveBuffer.get(data); 

     // Extract the actual bytes from our receivedBuffer 
     byte[] dataReceived = receiveBuffer.array(); 
     return dataReceived; 
    } 

을 그래서 당신이 볼 수 있듯이, 나는 5000의 크기로 새의 ByteBuffer를 작성하고 있지만, 이상적으로 나는이 일을하지 않으려는 다음과 같이

내 현재의 구현입니다. 그래서 내가 가지고있는 질문은 어떻게이 큰 크기의 ByteBuffer를 사용할 수 없으며,받은 데이터를 읽으므로 내 미사용 deconstruct 메시지 메서드를 사용할 수 있습니까?

답변

0

ByteBuffer에는 method get()이 있고 현재 위치에서 바이트를 반환합니다. 그래서 4 바이트를 먼저 읽고 크기를 얻을 수 있습니다.

+0

그래서 send 메서드에서 readBuffer라는 새 ByteBuffer를 만듭니다. 이상적으로 나는 그것을 제거하고 싶습니다. 내 최선의 옵션은 –

+0

까지 내가 알고있는 한 unwrap() 메서드는 ByteBuffer에 없습니다. 어쨌든 당신은 버퍼 – Vitaly

+0

에서 데이터를 복사하기 위해 자신의 바이트 []가 필요하고 대신에 remain() 메서드를 사용할 수 있습니다. – Vitaly