java - 服务器不解码数据包

标签 java sockets networking tcp bufferedreader

我正在为我的项目设计一个通信系统。但是,我在处理数据包时遇到了一些麻烦。我的通信系统是用java.net编写的,使用ServerSocket、Socket、BufferedReader和PrintWriter。

目前,我的系统每 500 毫秒监听一次数据包。它可以很好地处理登录数据包,但无法处理登录后数据包(发送 id、断开连接)。每 500 毫秒,我需要我的服务器监听登录和登录后数据包(发送 id、断开连接)。我将如何设计一种检测和处理登录后数据包的方法?登录数据包由握手代码、用户名和密码组成。登录后数据包(打印id、断开连接)由握手代码、用户id、事件id和其他事件参数组成。

使用 bufferedreader 和 printwriter 将数据包作为一行文本发送和接收。

这是我的服务器端解码器

    protected void decode(Socket server) throws Exception {
    final BufferedReader reader = new BufferedReader(new InputStreamReader(server.getInputStream()));
    final int handshake = Integer.parseInt(reader.readLine());
    if (handshake == LOGIN) {
        final Session session = new LoginSession(server, reader);
        session.read(-1);
    } else if (handshake == POST_LOGIN) {
        final int index = Integer.parseInt(reader.readLine());
        final int opcode = Integer.parseInt(reader.readLine());
        final Session session = store.get(index).getSession();
        session.reader = reader;
        session.read(opcode);
    }

}

@Override
public void run() {
    Socket server;
    try {
        server = serverSocket.accept();
        server.setTcpNoDelay(false);
        decode(server);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

这些是我的客户端 -> 服务器数据包

    public void sendLogin() {
    write.write("100");
    write.write('\n');
    write.write("raees2");
    write.write('\n');
    write.write("LOL2");
    write.write('\n');
    write.flush();
}

public void sendPrintId() throws NumberFormatException, IOException {
    final BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
    final int id = Integer.parseInt(reader.readLine());
    System.out.println(id);

    write.write("101");
    write.write('\n');
    write.write(Integer.toString(id));
    write.write('\n');
    write.write(Integer.toString(0));
    write.write('\n');
    write.write(Integer.toString(10003));
    write.write('\n');
    write.flush();
}

public void sendDisconnection() throws NumberFormatException, IOException {
    final BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
    final int id = Integer.parseInt(reader.readLine());
    System.out.println(id);

    write.write("101");
    write.write('\n');
    write.write(Integer.toString(id));
    write.write('\n');
    write.write(Integer.toString(1));
    write.write('\n');
    write.flush();
}

最佳答案

基本上,您只需要一个循环来继续从流中读取数据,直到对话完成。现在,它读取一条消息并终止。

我不确定你的协议(protocol)是如何工作的,但类似这样的东西可以提供一个起点:

protected void decode(Socket server) throws Exception {
    final BufferedReader reader = new BufferedReader(new InputStreamReader(server.getInputStream()));

    /*
     * Somewhere in this loop, detect your protocol's termination condition
     * and break out.
     */

    for (;;) {
        final int handshake = Integer.parseInt(reader.readLine());
        if (handshake == LOGIN) {
            final Session session = new LoginSession(server, reader);
            session.read(-1);
        } else if (handshake == POST_LOGIN) {
            final int index = Integer.parseInt(reader.readLine());
            final int opcode = Integer.parseInt(reader.readLine());
            final Session session = store.get(index).getSession();
            session.reader = reader;
            session.read(opcode);
        }
    }
}

如果您需要同时处理多个连接,您可能希望您的接受器线程为每个成功连接的连接启动一个新的客户端线程,因为 decode 在等待下一条消息。

关于java - 服务器不解码数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35528018/

相关文章:

java - 迭代拓扑搜索(DFS)

java - Maven 在 jar 中生成重复的 pom.xml 和 pom.properties 文件

java - 初学者 : Do while loop issue

c - 如何在C套接字(sys/socket.h)中获取客户端的地址和端口?

http - 如何通过http实现服务端和客户端的双向通信

c - Winpcap 代码 - 捕获在循环中丢失数据包

mysql - 使用c中的sendto函数发送mysql输出

java - Spring事务在异常后不回滚

C++ 网络,recv() 无缘无故失败(?)

c - 我们如何使用C中的非连接套接字udp将数据发送到ipv4和ipv6 google接口(interface)?