2012-06-28 4 views
0
SocketChannel channel = (SocketChannel) key.channel(); 

    ByteBuffer buffer = ByteBuffer.allocate(1024); 
    int numRead = -1; 
    try { 
     numRead = channel.read(buffer); 
     System.out.println("numRead: " + numRead); 
    } 
    catch (IOException e) { e.printStackTrace();} 
    if (numRead == -1) { 
     this.dataMap.remove(channel); 
     Socket socket = channel.socket(); 
     SocketAddress remoteAddr = socket.getRemoteSocketAddress(); 
     System.out.println("Connection closed by client: " + remoteAddr); 
     channel.close(); 
     key.cancel(); 
     return; 
    } 
    System.out.println("Got: " + new String(buffer.array(), "windows-1251")); 

소켓에서 1024 바이트의 데이터를 읽습니다. 이 경우 모든 메시지가 결합되고 마지막 메시지가 완전히 표시되지 않습니다. 어떻게 메시지 분리 자 '|'가 나오기 전에 버퍼에 데이터를 읽습니까? ? 각 메시지를 개별적으로 수신하고 싶습니다.Java SocketChannel 알 수없는 길이의 메시지 읽기

+0

소켓 API가이 작업을 수행합니다. 이미 버퍼에 있습니다. – Woot4Moo

+1

여기에 좋은 읽을 거리입니다. https://github.com/robbiehanson/CocoaAsyncSocket/wiki/CommonPitfalls는 귀하가 무엇을 요구하는지에 대해 이야기합니다. 라이브러리는 obj-c를위한 것이지만 기사는 tcp/udp가있는 일반적인 함정에 대한 것입니다. 적용 가능합니다. –

답변

0

프로토콜에 따라 다르지만 프로토콜이 메시지 분리 문자를 기반으로하는 경우 유일한 옵션은 차단하지 않고 최대한 많이 읽은 다음 읽은 내용을 스캔하여 구분 기호를 찾는 것입니다. 연결이 닫힐 때까지 (또는 연결을 닫기로 결정할 때까지) 루프에서이 작업을 수행해야합니다.

물론 여러 메시지를 한 번에 읽을 수도 있고 부분 메시지 일 수도 있으므로 적절하게 처리해야합니다.

+0

불행히도이 방법은 저에게 맞지 않습니다. – user1221483

+0

크게 다른 방법이 없기 때문에 수치 스럽습니다. 프로토콜이 다른 경우 (예 : 모든 메시지가 메시지 길이가 포함 된 고정 크기 헤더로 시작되는 경우). – biziclop

0

TCP에 메시지와 같은 것이 없습니다. 이것은 바이트 스트림 API입니다. 메시지를 원할 경우 구분 기호, STX/ETX 쌍, 길이 단어 접두사, 자체 기술 프로토콜 등을 통해 메시지를 직접 구현해야합니다.

관련 문제