2012-06-28 47 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對,長度字前綴,自描述協議等。