2014-02-23 70 views
0

我正在使用SocketChannel與遠程服務器進行通信。我使用socketChannel.write()發送數據,沒有錯誤和異常,但是,服務器日誌指示沒有收到數據;客戶端tcp流量監視器還顯示未發送ByteBuffer中的字符串消息。SocketChannel write()返回時沒有錯誤,但實際上沒有發送數據

任何人都可以給我一個提示,爲什麼這是這種情況?謝謝!

public class Client implements Runnable { 
    SocketChannel socketChannel; 
    Selector selector; 
    SelectionKey key; 
    ByteBuffer inbuf, outbuf; 
    int id; 
    @Override 
    public void run() { 
    try { 
     // prepare inbuf and outbuf 
     inbuf = ByteBuffer.allocate(10000); 
     outbuf = ByteBuffer.allocate(10000); 

     // prepare a socket channel for communication 
     socketChannel = SocketChannel.open(); 
     socketChannel.connect(new InetSocketAddress("<remote server ip>",)); 
     selector = Selector.open(); 
     socketChannel.configureBlocking(false); 
     key = socketChannel.register(selector, SelectionKey.OP_READ 
       | SelectionKey.OP_WRITE); 

     while (selector.select() > 0) { 

      if (key.isReadable()) { 
       // read from channel when server sends data 
       read(); 
      } 

      if (key.isWritable()) { 
       // write 
       Random r = new Random(500); 
       write("b", r.nextInt(), r.nextInt()); 
       for (int i = 0; i < 10; i++) { 
        // write a message to server after 1 second 
        Thread.sleep(1000); 
        write("m", r.nextInt(), r.nextInt()); 
       } 
       write("e", r.nextInt(), r.nextInt()); 
      } 
     } 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

} 

private void write(String action, int x, int y) throws IOException { 
    String msg = String.format("%s:%d:%d:%d", action, id, x, y); 
    int r=outbuf.remaining(); 

    outbuf.put(msg.getBytes()); 
    int rBytes = outbuf.remaining(); 
    boolean connected = socketChannel.isConnected(); 
    Socket sock = socketChannel.socket(); 

    if (connected && sock.isConnected() && !sock.isOutputShutdown()) 
>>>>>>>>>> socketChannel.write(outbuf); 
    else 
     System.out.println("Connection broken!"); 

    System.out.printf("Client %d told server:%s\n", id, msg); 
    //outbuf.clear(); 
} 

    ... //read omitted here 
+0

你翻轉()ByteBuffer的?編輯:不,你沒有......我在寫答案。 – xp500

+0

謝謝!您好@ EJP,您能否看看我問的另一個問題?謝謝。 http://stackoverflow.com/questions/21965436/socketchannel-selector-vs-plain-socket?lq=1 – wizoleliam

回答

5

將東西放入緩衝區或讀入東西后,您必須翻轉緩衝區以寫入或從中獲取數據。檢查Buffer類中的flip()方法。文檔說

翻轉此緩衝區。限制設置爲當前位置,然後位置設置爲零。如果標記被定義,那麼它被丟棄。 經過一系列通道讀取或放置操作後,調用此方法以準備一系列通道寫入或相對獲取操作。

看跌所以以後加入buffer.flip()應該做的伎倆:)

+0

+1,不要忽略'write()返回的值。「在這裏它應該是零情況,這應該觸發警鐘。 – EJP

+0

謝謝@ xp500,它的工作原理!我確實讀到了ByteBuffer或Buffer類一般可以在讀取和寫入模式之間「翻轉」。既然這個工作,這是否意味着我把一些字節放在ByteBuffer後,SocketChannel的write()方法實際上會讀取緩衝區並通過socket的outputStream寫入它?謝謝 – wizoleliam

+0

@EJP,謝謝你的提示! – wizoleliam

相關問題