【问题标题】:How to manage lots of incoming packets如何管理大量传入的数据包
【发布时间】:2014-12-20 21:33:43
【问题描述】:

我有一个带有远程客户端的套接字服务器,它可以正常工作。打开客户端并登录后,我注意到有时会出现错误,这似乎是由于客户端在不应该读取 int 时造成的。

登录后,服务器会向客户端发送一系列消息/数据包,这些消息/数据包从字符串消息到用于在客户端加载变量的信息。

有时,在登录时,会抛出错误,表明客户端已读取大小为 0 或非常大的数据包。在将大数字转换为ascii时,我曾经发现它有点像字符串“sk”。 (我在我的代码中找到了这个字符串,所以它不是完全随机的)。

查看我的代码,我不确定为什么会这样。客户端是否有可能在错误的时间读取 int?如果是这样,我该如何解决这个问题?

        InetAddress address = InetAddress.getByName(host);
        connection = new Socket(address, port);
        in = new DataInputStream(connection.getInputStream());
        out = new DataOutputStream(connection.getOutputStream());
        String process;
        System.out.println("Connecting to server on "+ host + " port " + port +" at " + timestamp);
        process = "Connection: "+host + ","+port+","+timestamp + ". Version: "+version;
        write(0, process);
        out.flush();
        while (true) {
            int len = in.readInt();
            if (len < 2 || len > 2000) {
                throw new Exception("Invalid Packet, length: "+len+".");
            }
            byte[] data = new byte[len];
            in.readFully(data);
            for (Byte b : data) {
                System.out.printf("0x%02X ",b);
            }
            try {
                reader.handlePackets(data);
            } catch (Exception e) {
                e.printStackTrace();
                //connection.close();
                //System.exit(0);
                //System.out.println("Exiting");
            }
        }


//Here is code for my write function (Server sided):
public static void write(Client c, Packet pkt) {
    for (Client client : clients) {
        if (c.equals(client)) {
            try {
                out.writeInt(pkt.size());
                out.write(pkt.getBytes());
                out.flush();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}

所以看看 write 函数,我真的不明白它是如何混淆客户端并让它读取一个数据包两次的数据包大小(至少我认为这是正在发生的事情)。

如果您需要更多信息,请询问我。

【问题讨论】:

标签: java sockets client packet server


【解决方案1】:

客户端代码看起来不错,服务器端代码看起来也不错。

最可能的问题是,这是多线程和(不正确的)同步的某种问题。例如,可能有两个服务器端线程试图同时向同一个客户端写入一个数据包。

也有可能您的Packet 类对size()getBytes() 的实现不一致...或者一个线程正在修改Packet 对象而第二个线程正在发送它。

【讨论】:

  • 什么会导致不正确的同步?另外,据我所知,每次服务器写入数据包时,它都是一个新数据包,所以它不应该修改另一个数据包(我不认为)。我在想有一个与大小有关的错误,但我还没有找到它。如果是这种情况,考虑到每次发送相同的数据包,每次登录时不应该有这个问题吗?相反,它只发生在 40-60% 的时间里。
  • “什么会导致不正确的同步?” - 不正确的代码。 “相反,它只发生在 40-60% 的时间。”。这与您的应用程序同步问题不一致。
  • 你能说更多吗?我在发送/接收之前和之后打印了数据包大小,并且大小似乎没有改变。但是,问题仍然存在,偶尔我仍然会收到大小为 0 的数据包(登录时)。
  • 我可以为此写一整本书。但这将是多余的,因为其他人已经这样做了。我建议您阅读有关编写并发/多线程程序的 Oracle Java 教程部分,特别注意其中涉及同步和线程安全的部分。
  • 糟糕......它与同步问题一致。错字。
猜你喜欢
  • 1970-01-01
  • 2020-03-05
  • 2015-04-20
  • 1970-01-01
  • 1970-01-01
  • 2020-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多