2016-02-12 72 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()除非在此情况下没有缓冲流,否则不会执行任何操作。