Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java套接字连接正在淹没网络或导致高ping_Java_Android_Sockets_Connection_Wireless - Fatal编程技术网

Java套接字连接正在淹没网络或导致高ping

Java套接字连接正在淹没网络或导致高ping,java,android,sockets,connection,wireless,Java,Android,Sockets,Connection,Wireless,我的java套接字代码有点问题。 我正在编写一个android客户端应用程序,它通过直接(!)无线连接将数据发送到我电脑上的java多线程套接字服务器。它工作得很好,但我想为移动应用改进它,因为它现在非常耗电。当我删除代码中的两行特殊代码时,我的移动设备(htc one x)的cpu使用率是完全正常的,但是我的连接似乎有很高的ping速率或者类似的东西 下面是一个服务器代码片段,我在其中接收客户端数据: while(true) { try { .

我的java套接字代码有点问题。 我正在编写一个android客户端应用程序,它通过直接(!)无线连接将数据发送到我电脑上的java多线程套接字服务器。它工作得很好,但我想为移动应用改进它,因为它现在非常耗电。当我删除代码中的两行特殊代码时,我的移动设备(htc one x)的cpu使用率是完全正常的,但是我的连接似乎有很高的ping速率或者类似的东西

下面是一个服务器代码片段,我在其中接收客户端数据:

while(true)
  {
    try {
                   ....
            Object obj = in.readObject();
            if(obj != null) {
                Class clazz = obj.getClass();
                String className = clazz.getName();
                if(className.equals("java.lang.String")) {
                    String cmd = (String)obj;
                    if(cmd.equals("dc")) {
                        System.out.println("Client "+id+" disconnected!");
                        Server.connectedClients[id-1] = false;
                        break;
                    }
                    if(cmd.substring(0,1).equals("!")) {
                        robot.keyRelease(PlayerEnum.getKey(cmd,id));
                    }
                    else {
                        robot.keyPress(PlayerEnum.getKey(cmd,id));
                    }

                }
            }

    } catch ....
这是客户端部分,我在while循环中发送数据:

private void networking() {
    try {
        if(client != null) {
            ....
                out.writeObject(sendQueue.poll());

            ....
        }
    } catch ....
当我写这篇文章时,每当while循环执行时,我都会发送数据。。当sendQueue为空时,将发送空的“对象”。这会导致“高”网络流量和“高”cpu使用率。但是:所有发送评论几乎都会立即收到

当我将代码更改为以下内容时:

while(true)
...
if(sendQueue.peek() != null) {
    out.writeObject(sendQueue.poll());
}
...
cpu使用率完全正常,但我有一些滞后。。命令到达的速度不够快。。正如我所说的,如果我在每次执行时发送数据(使用空对象),那么它工作得很好(除了cpu使用情况)。但我确信这是一种非常粗糙的编码风格,因为我有点像洪水一样淹没了整个网络。有什么提示吗

我做错了什么


谢谢你的帮助

真诚地属于你,
maaft

您的代码的CPU密集型版本正在向输出流中注入
null
值。它们被视为要传输的数据。尽管您的服务器明确地忽略了它们,但它们也有助于最终强制任何有用的数据通过

peek
修改代码更合理。在
writeObject
之后调用
flush
是一种很好的形式。否则,写入的对象可能会卡在输出缓冲区中,等待更多的项出现。对于多个对象一起发送的情况,缓冲是一种性能优化。不进行缓冲的流类不需要刷新

更好的是:

Object item = sendQueue.poll();
if (item != null) {
    out.writeObject(item);
    out.flush();  // maybe not needed, depending on the class of your stream 
}
这稍微快一点;如果您打算立即进行
poll
,那么评估
peek
是没有意义的


此外,在将套接字传递给
SocketOutputStream
之前,在套接字上调用
socket.setTcpNoDelay(true)
(假设这就是创建输出流的方式)。这会禁用,这可能不一定是节约网络带宽的最佳决策,但它是一种快速的方法,可以检查除了调整TCP发送/接收缓冲区之外,客户端和服务器是否正常工作。如果您直接连接到服务器,我根本不担心禁用Nagle算法。

您的代码的CPU密集型版本正在向输出流中注入
null
值。它们被视为要传输的数据。尽管您的服务器明确地忽略了它们,但它们也有助于最终强制任何有用的数据通过

peek
修改代码更合理。在
writeObject
之后调用
flush
是一种很好的形式。否则,写入的对象可能会卡在输出缓冲区中,等待更多的项出现。对于多个对象一起发送的情况,缓冲是一种性能优化。不进行缓冲的流类不需要刷新

更好的是:

Object item = sendQueue.poll();
if (item != null) {
    out.writeObject(item);
    out.flush();  // maybe not needed, depending on the class of your stream 
}
这稍微快一点;如果您打算立即进行
poll
,那么评估
peek
是没有意义的


此外,在将套接字传递给
SocketOutputStream
之前,在套接字上调用
socket.setTcpNoDelay(true)
(假设这就是创建输出流的方式)。这会禁用,这可能不一定是节约网络带宽的最佳决策,但它是一种快速的方法,可以检查除了调整TCP发送/接收缓冲区之外,客户端和服务器是否正常工作。如果您直接连接到服务器,我根本不担心禁用Nagle算法。

您应该使用阻塞队列,以便poll()阻塞,而不是返回null。发送null没有任何意义,这只是浪费每个人的时间、带宽和金钱。

您应该使用阻塞队列,以便poll()阻塞,而不是返回null。发送空值没有任何意义,这只是浪费每个人的时间、带宽和金钱。

作为进一步说明,您可能想看看Android的ARO工具,它可以帮助您优化应用程序,包括网络使用情况

作为进一步说明,您可能想看看Android的ARO工具,它可以帮助您优化应用程序,包括网络使用情况

谢谢你的快速回答!我已经用flush()方法尝试过了,但是我的命令仍然很晚才到达。奇怪的是,泛滥的网络导致命令几乎立即到达。可能是因为套接字需要一点时间对“新”数据而不是稳定的数据流作出反应??我无法指出..@user1461100-您如何准确构建所涉及的输出流?也就是说,它们是什么类型的,你对它们设置了什么或传递给它们的构造函数?@user1461100-我将在这一天剩下的时间里离线,但我添加了将Nagle算法关闭为问题的指导,希望这可能是你的问题。谢谢你,你是天才!禁用Nagle算法完全解决了我的问题!:)谢谢你的快速回答!我已经用flush()方法尝试过了,但是我的命令仍然很晚才到达。奇怪的是,泛滥的网络导致命令几乎立即到达。可能是因为套接字需要一点时间对“新”数据而不是稳定的数据流作出反应??我无法指出..@user1461100-您如何准确构建所涉及的输出流?Th