【发布时间】:2016-02-12 19:21:53
【问题描述】:
所以我有一个客户端/服务器游戏,每次客户端移动游戏输出到 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”(来自 join 方法)并且一切运行顺利,但是每个后续消息我都会收到“错误消息”作为输出,这意味着服务器从未收到应该通过流发送的任何其他消息。
例如,当使用一些琐碎的参数调用放置的函数时,我会在控制台上打印 13 个“错误消息”副本。
所以我的问题是我错过了什么? DataOutputStream 是否发送了我想要的内容,我只是解释不正确,还是发生了更复杂的事情。
在弄乱程序后,我删除了刷新语句。我还打印了客户端发送的内容和服务器看到的内容。客户端正在发送正确的东西,但服务器似乎无法接收到它们。相反,它看到 7 个零(空)。 1 表示字母“P”,6 表示更多,我认为这三个整数。
我还包括一个指向我的 github 的链接,用于访问完整代码(位于 src 文件夹中): https://github.com/michaelrinos/Connect-Fout-Client-Server/tree/TCP
modelproxy 类的输出(客户端):
Writting J and "john1" <Byte> <UTF>
Sending: 0<Byte> 0<Byte> 5<Byte>
第二个modelproxy类的输出(客户端):
Writting J and "john2" <Byte> <UTF>
viewproxy 类的输出(服务器端):
Received J and john1
Received J and john2
0
Bad message
0
Bad message
0
Bad message
5
Bad message
您可以看到虽然数字是正确的,但我丢失了前导字符。
【问题讨论】:
-
我建议你打印你得到的字节。它可以为您提供有关问题所在的线索。
-
嗯,我尝试的一件事是移除开关盒并打印出所有读入的字节,即使这样我也会得到不同的输出,根据客户端应该发送的是:(74( 'J'), ASCII 二进制文件中的玩家名, 80 ('P'), 0, 0, 10) 另一方面服务器接收 (74 ('J'), client1, 74 ('J'), client2, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2)
-
如果客户端收到
client1和client2你一定是发送了这些,因为没有一个简单的错误会想出这样的真实数据。 -
Java
char是 16 位(不是 8 位)。 -
@ElliottFrisch 是的,我明白你的意思,但 DataOutputStream 的重点是它支持通过首先对它们进行二进制编码、发送它们,然后通过 DataInputStream 解码它们的过程来发送 java 原语。同样在我使用 UDP 和 DataOutputStream 编写的代码的类似版本中,客户端发送相同的消息 out.writeByte('P') 并且服务器能够成功接收消息
标签: sockets java-8 datainputstream dataoutputstream