繁体   English   中英

Java套接字连接正在泛洪网络或导致高ping

[英]Java Socket Connection is flooding network OR resulting in high ping

我的Java套接字代码有一点问题。 我正在编写一个android客户端应用程序,该应用程序通过直接(!)无线连接将数据发送到PC上的java多线程套接字服务器。 它工作正常,但我想针对移动应用程序进行改进,因为到目前为止它非常耗电。 当我在代码中删除两条特殊行时,我的移动设备的CPU使用率(htc one x)完全可以,但是我的连接似乎具有较高的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为空时,将发送一个空的“ Object”。 这导致“高”网络流量和“高” cpu使用率。 但是:所有发送的评论几乎都会立即收到。

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

while(true)
...
if(sendQueue.peek() != null) {
    out.writeObject(sendQueue.poll());
}
...

cpu的使用完全可以,但是我遇到了一些滞后..命令不能足够快地到达..正如我所说,如果我每次发送数据(带有空对象)的话,它都可以正常工作(除了cpu的使用)执行。 但是我敢肯定,这是非常粗糙的编码风格,因为我有点淹没网络。 有什么提示吗?

我究竟做错了什么??


谢谢你的帮助!

顺祝商祺

代码的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) (假设这是创建输出流的方式)。 这禁用了Nagle算法 ,这不一定是节省网络带宽的最佳决定,但它是一种检查方法,除了调整TCP发送/接收缓冲区之外,它还可以检查客户端和服务器是否正常工作。 如果您直接连接到服务器,则完全不用担心禁用Nagle算法。

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

进一步说明,您可能想看看Android的ARO工具,它可以帮助您优化应用程序,包括网络使用率。 http://developer.att.com/developer/legalAgreementPage.jsp?passedItemId=9700312

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM