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 文件夹中(: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() 除非下面有一个缓冲流,否则什么都不做,而在这种情况下没有。

相关内容

  • 没有找到相关文章

最新更新