2014-04-24 30 views
0

尊重閱讀所有郵件,AsynchronousSocketChannel寫/在一個

我嘗試使用新的Java NIO2到客戶端和服務器端建立異步的SocketChannel和溝通,但問題是,我發送的所有郵件到插座上服務器,套接字全部讀取爲一條消息。這裏是代碼:

創建寫入處理和讀取數據:

ReadHandler:

public class ReadHandler implements CompletionHandler<Integer, Msg> { 


private AsynchronousSocketChannel _socket; 
private SocketHandler _socketHandler; 

private ByteBuffer _buffer; 

public ReadHandler(SocketHandler socketHandler) { 

    this._socketHandler = socketHandler; 
    _buffer = ByteBuffer.allocate(100); 

    this._socket = this._socketHandler.getSocket(); 
    this._socket.read(_buffer, null, this); 
} 

@Override 
public void completed(Integer result, Msg attachment) { 

    System.out.println("readdddd " + result); 

    String message = new String(_buffer.array()); 
    System.out.println("mess:" + message); 

} 

@Override 
public void failed(Throwable exc, Msg attachment) { 
    System.out.println(exc.getMessage()); 
} 

}

ClientWriteHandler

public class ClientWriteHandler implements CompletionHandler<Integer, Msg> { 

private AsynchronousSocketChannel _socket; 
private ClientSocket _clientHandler; 

private ByteBuffer _buffer; 

public ClientWriteHandler(ClientSocket clientHandler) { 


    this._clientHandler = clientHandler; 
    _buffer = ByteBuffer.allocate(2048); 
    this._socket = this._clientHandler.getSocket(); 
} 

@Override 
public void completed(Integer result, Msg attachment) { 

    System.out.println("write " + result); 
    _buffer.clear(); 
} 

@Override 
public void failed(Throwable exc, Msg attachment) { 
    System.out.println(exc.getMessage()); 
} 

public void write(String data) { 
    _buffer = ByteBuffer.allocate(2048); 
    this._socket.write(_buffer.wrap(data.getBytes()), new Msg(), this); 

} 

}

然後我調用write方法2時

socket = AsynchronousSocketChannel.open(); 
     socket.connect(new InetSocketAddress("localhost", port)).get(); 
     writeHandler = new ClientWriteHandler(this); 
     writeHandler.write("hellooo server :)"); 
     writeHandler.write("hellooo server again :)"); 

我嘗試在字節緩衝區,但沒有效果明確的使用()函數。任何建議?

回答

0

您發送第一.WRITE()調用的幾個字節,並在第二次調用發送幾個字節.WRITE()。服務器接收它們。 TCP是以字節爲導向的。如果您想要任何信息,您必須單獨發送您自己發送的郵件,例如通過特殊換行符或XML標籤。

+0

Oke但如果我的ByteBuffer已滿,我該怎麼辦,我嘗試清除bytebuffer,但後來收到錯誤消息 線程「main」中的異常java.nio.channels.WritePendingException – user2803095

0

我在此工作,我發現解決方案及其工作正如我所想象的。

內ClientWrite處理器的我加DATAS列表並設置寫入方法內部在try..catch檢查write()方法是finihed,如果寫的是仍在進行中我新的字符串添加到列表DATAS。寫入方法完成後,我會檢查數據列表以查找新消息並再次寫入消息。

public class ClientWriteHandler implements CompletionHandler<Integer, ByteBuffer> { 

private AsynchronousSocketChannel _socket; 
private ClientSocket _clientHandler; 

private ByteBuffer _buffer; 
private List<String> datas; 

private boolean finished; 

public ClientWriteHandler(ClientSocket clientHandler) { 


    this._clientHandler = clientHandler; 
    _buffer = ByteBuffer.allocate(2048); 
    this._socket = this._clientHandler.getSocket(); 
    finished = true; 
    datas = new ArrayList<>(); 
} 

@Override 
public void completed(Integer result, ByteBuffer attachment) { 

    System.out.println("client write complete " + result); 

    if(datas.size() > 0) { 
     this._socket.write(_buffer.wrap(datas.remove(0).getBytes()), _buffer, this); 
    } 
    else { 
     ///// 
    } 
} 

@Override 
public void failed(Throwable exc, ByteBuffer attachment) { 
    System.out.println(exc.getMessage()); 
} 

public void write(String data) { 

    try { 
     //finished = false; 
     this._socket.write(_buffer.wrap(data.getBytes()), _buffer, this); 
    }catch(WritePendingException ex) { 

     datas.add(data); 
    } 
} 

}

此外,我在附件發送緩衝器。 閱讀完成後,在ReadHandler中清除ByteBuffer並再次調用read()方法,所以下一次閱讀我得到了新行,現在我不需要設置行分隔符。

public class ReadHandler implements CompletionHandler<Integer, ByteBuffer> { 


private AsynchronousSocketChannel _socket; 
private SocketHandler _socketHandler; 

private ByteBuffer _buffer; 

public ReadHandler(SocketHandler socketHandler) { 

    this._socketHandler = socketHandler; 
    _buffer = ByteBuffer.allocate(2048); 

    this._socket = this._socketHandler.getSocket(); 
    this._socket.read(_buffer, _buffer, this); 
} 

@Override 
public void completed(Integer result, ByteBuffer attachment) { 

    attachment.flip(); 
    System.out.println("readdddd " + result); 

    String message = new String(attachment.array()); 
    System.out.println("mess:" + message); 

    _buffer.clear(); 
    this._socket.read(_buffer, _buffer, this); 

} 

@Override 
public void failed(Throwable exc, ByteBuffer attachment) { 
    System.out.println(exc.getMessage()); 
} 

}

現在這個工程這麼好,但我會檢查這個代碼將如何表現時,我繼續着更爲複雜的東西。你認爲這個解決方案可以嗎?

2

WritePendingException不是因爲緩衝區已滿而被拋出。它被拋出是因爲寫作沒有完成,但另一個開始寫。