所以我有一个客户端/服务器游戏,每次客户端移动游戏输出到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 文件夹中(:https://github.com/michaelrinos/Connect-Fout-Client-Server/tree/TCP
模型代理类(客户端(的输出:
Writting J and "john1" <Byte> <UTF>
Sending: 0<Byte> 0<Byte> 5<Byte>
第二个模型代理类(客户端(的输出:
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
你可以看到虽然数字是正确的,但我失去了前导字符。
这不可能是真正的代码。否则,您将收到"J"、0x00、0x07、"player1"等,其中0x0007是 writeUTF().
放置在那里的长度前缀 确保您阅读的所有内容都是用writeUTF().
编写的 readUTF()
您可能还正在向此处未显示的流写入其他内容。
你需要单独捕获EOFException
,并在捕获时中断读取循环;并且您不需要忽略IOExceptions.
DataOutputStream.flush()
除非下面有一个缓冲流,否则什么都不做,而在这种情况下没有。