2016-02-12 75 views
0

所以我有一個客戶端/服務器遊戲,每次客戶端移動遊戲輸出到DataOutputStream並由DataInputStream接收時,第一條消息是一條連接消息,它告訴服務器用戶名(該消息被正確接收),但所有後續消息都會偏斜。DataOutputStream和DataInputStream溝通不暢

所以我初始化這樣流連接到服務器/客戶端

private DataInputstream out = new DataOutputStream(socket.getOutputStream());

private DataInputStream in = new DataInputStream(socket.getInputStream());

的方法來發送消息到服務器後:

/** 
* Tells server someone has joined 
*/ 
public void join(ViewProxy proxy, String session) throws IOException { 
    out.writeByte('J'); 
    out.writeUTF(session); 
    out.flush(); 
} 

/** 
* tells server that a player took these numbers from a heap 
* 
* @param x the heap 
* @param y the number of items removed 
* @throws IOException 
*/ 

@Override 
public void placed(int id, int x, int y) throws IOException { 
    out.writeByte('P'); 
    out.writeInt(id); 
    out.writeInt(x); 
    out.writeInt(y); 
    out.flush(); 
} 

/** 
* Tells server to start a new game 
* 
* @throws IOException 
*/ 
@Override 
public void newgame() throws IOException { 
    out.writeByte('N'); 
    out.flush(); 
} 

/** 
* Tells server to quit the game 
* 
* @throws IOException 
*/ 
@Override 
public void quit() throws IOException { 
    out.writeByte('Q'); 
    out.flush(); 
} 

最後如何服務器讀取消息:

private class ReaderThread extends Thread { 
    public void run() { 
     try { 
      for (;;) { 
       String session; 
       byte b = in.readByte(); 

       switch (b) 
       { 
        case 'J': 
         session = in.readUTF(); 
         System.out.println("Received J"); 
         viewListener.join (ViewProxy.this, session); 
         break; 
        case 'P': 
         System.out.println("Received P"); 
         int id = in.readInt(); 
         int r = in.readInt(); 
         int c = in.readInt(); 
         viewListener.placed (id, r, c); 
         break; 
        case 'N': 
         System.out.println("Received N"); 
         viewListener.newgame(); 
         break; 
        case 'Q': 
         System.out.println("Received Q"); 
         viewListener.quit(); 
         break; 
        default: 
         System.err.println ("Bad message"); 
         break; 
       } 
      } 
     } catch (IOException exc) { 
     } finally { 
      try { 
       socket.close(); 
      } catch (IOException exc) { 
      } 
     } 
    } 
} 

當我運行服務器後,客戶端服務器接收到初始'J'(來自連接方法),一切運行平穩,但後續消息我得到一個「壞消息」作爲輸出意味着服務器從未收到任何應該通過流發送的其他消息。

例如,當放置的函數被一些微不足道的參數調用時,我得到13個打印到控制檯的「壞消息」副本。

所以我在這裏的問題是我失去了什麼? DataOutputStream是否發送了我想要的內容,我只是不正確地解釋它,或者是更復雜的事情。

搞亂了程序後,我刪除了刷新語句。我還印刷了客戶正在發送的內容以及服務器正在看到的內容。客戶端正在發送正確的東西,但服務器似乎無法接通它們。它會看到7個零(null)。 1代表字母'P',6代表更多的我認爲是三個整數。

而且我包括一個鏈接到我的github用於訪問完整的代碼(位於src文件夾): 從modelproxy類(客戶端)https://github.com/michaelrinos/Connect-Fout-Client-Server/tree/TCP

輸出:

Writting J and "john1" <Byte> <UTF> 
Sending: 0<Byte> 0<Byte> 5<Byte> 
從第二modelproxy類(客戶端)

輸出:從viewproxy類(服務器端)

Writting J and "john2" <Byte> <UTF> 

輸出:

Received J and john1 
Received J and john2 
0 
Bad message 
0 
Bad message 
0 
Bad message 
5 
Bad message 

你可以看到,雖然數字是正確的,但我失去了領先的字符。

+0

我建議你打印你得到的字節。它可以讓你知道什麼是錯的。 –

+0

我嘗試過的其中一件事是去除開關盒,並打印出所有讀入的字節,然後我得到不同的輸出應根據客戶端發送的內容是:(74('J'),playername in ascii binary,80('P'),0,0,10)另一方面,服務器接收(74('J'),client1,74('J'),client2,0,0,0,0, 0,0,0,0,0,0,0,2) –

+0

如果客戶端收到'client1'和'client2',你必須發送它們,因爲沒有簡單的錯誤會出現像這樣的真實數據。 –

回答

0

這不能是真正的代碼。否則,您將收到'J',0x00,0x07,「player1」等,其中0x0007是放在那裏的長度前綴writeUTF().確保您用readUTF()讀取的所有內容都是用writeUTF().編寫的您也可能正在爲其寫入其他內容這裏沒有顯示。

你需要分別抓住EOFException,當你抓到它時就跳出讀取循環;並且您不需要忽略IOExceptions.

DataOutputStream.flush()除非在此情況下沒有緩衝流,否則不會執行任何操作。