首页 文章

DataOutputStream和DataInputStream的通信错误

提问于
浏览
0

所以我有一个客户端/服务器游戏,每次客户端将游戏输出移动到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发送我想要的东西我只是错误地解释它或者是更复杂的事情 .

搞乱程序后我删除了flush语句 . 我还打印了客户端发送的内容以及服务器看到的内容 . 客户端正在发送正确的东西,但服务器似乎无法接收它们 . 它反而看到7个零(null) . 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

你可以看到虽然数字是正确的,但我失去了领先的字符 .

1 回答

  • 0

    这可以't be the real code. Otherwise you would have received ' J',0x00,0x07,"player1"等,其中0x0007是放在那里的长度前缀 writeUTF(). 确保您使用 readUTF() 读取的所有内容都是用 writeUTF(). 编写的 . 您可能还会在此处未显示的内容中写入其他内容 .

    您需要单独捕获 EOFException ,并在捕获它时突破读取循环;你不必忽视 IOExceptions.

    除非在下面有缓冲流,否则 DataOutputStream.flush() 什么都不做,在这种情况下不存在 .

相关问题