Android 中的 TCP 套接字

TCP socket in Android

提问人:Ayesha 提问时间:4/16/2022 最后编辑:user207421Ayesha 更新时间:4/18/2022 访问量:304

问:

我的问题是我在android中实现了一个TCP套接字客户端,它不断向服务器发送“Hello”消息以保持客户端-服务器连接并从服务器接收消息。

在 Android 中,我初始化了一个布尔变量,如果我的应用程序在后台,它会控制线程,我将“AppConfig.finished”变量设置为 true inactivity on pause 和 on stop 方法,以停止套接字线程并在恢复状态下使其为 false。

但是我的应用程序消耗高 CPU 使用率,这使我的应用程序变慢,我已经在 android 的分析器中检查了它。请帮我优化它。

代码如下。

public class MyTcp extends Thread{


private BufferedInputStream inputStream;
private BufferedOutputStream outputStream;
private Socket MySock;
private static SocketStatus SS;
private int ConnectAttemptCount = 0;
private CheckConnectionStatus CheckStatus = null;
public boolean FirstAttempt = true;
public boolean Continue = true;
private boolean isDirectChecked = false;
String tempData = "";
private final ArrayBlockingQueue<String> Queue = new ArrayBlockingQueue<>(100);

public MyTcp(SocketStatus SS) {
    MyTcp.SS = SS;
    MyTcp.SS.isConnected = false;

    setDaemon(true);
    Thread t = new Thread(new DequeueMessageThread());
    t.setName(SS.SocketName + " DequeqeMessageThread");
    t.start();
    setName(SS.SocketName);

}


public void Dispose() {
    try {

        Continue = false;
        SS.isConnected = false;
        if(inputStream != null) {
            inputStream.close();
        }

        if(outputStream !=null) {
            outputStream.close();
        }
        if(MySock != null) {
            MySock.close();
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public void run() {

    if(!Logs.isFinished) {
        try {

            while (Continue) {
                if (SS.isConnected) {
                    String fromServer = ReceiveMsg();
                    if (fromServer.compareTo("") != 0) {
                        Queue.put(fromServer);
                    }
                    ConnectAttemptCount = 0;

                } else {
                    if (ConnectAttemptCount < SS.ConnectAttempt) {
                        println("run>>" + "Connection Attempt" + ConnectAttemptCount);
                        ConnectAttemptCount++;
                        Connect();

                    } else {

                        println("run>>" + "Unable To Connect to server");
                        break;
                    }
                }
            }

        } catch (Exception e) {
            println("run Exception>>" + e);
        }
    }

}

public void Connect() {
    if(!Logs.isFinished) {
        try {
            if (SS.isDoQueueEmptyOnConnect) {
                Queue.clear();
                tempData = "";
            }
            if (FirstAttempt) {
                FirstAttempt = false;
            } else {


                Utilities.println("Trying to connect with " + SS.ServerIP + " on Port " + SS.Port);
                _fireStatsEvent(Status.Reconnecting, "Trying to connect with " + SS.ServerIP);
                Random generator = new Random();
                long wait = (long) generator.nextInt(3000) + 500;
                Thread.sleep(wait);
            }


            MySock = (Socket) AccessController.doPrivileged(new PrivilegedAction() {

                public Object run() {


                    try {
                        // Start Secure Code
                        return (new Socket(SS.ServerIP, SS.Port));
                        // End Secure Code
                    } catch (Exception e) {
                        println("Connect Exception>>" + e.toString());
                    }


                    return null;
                }
            });


            if (MySock != null) {


                SS.isConnected = true;
                SocketStatus.MySock = MySock;
                inputStream = new BufferedInputStream(MySock.getInputStream());
                outputStream = new BufferedOutputStream(MySock.getOutputStream());

                Utilities.println("Connection established with " + SS.ServerIP + " on Port " + SS.Port);

                if (SocketStatus.EnablePingPong) {
                    if (CheckStatus != null) {
                        CheckStatus.Dispose();
                    }
                    SS.LastMsgTime = new Date();
                    CheckStatus = new CheckConnectionStatus(SS, this);
                    CheckStatus.setName(SS.SocketName + "Connection Status Thread");
                    CheckStatus.start();
                }


            }

        } catch (Exception e) {
            println("Connect>>" + e);
        }

        int ConnectToIPCount = 0;
        if (!SS.isConnected) {

            while (!SS.isConnected && ConnectToIPCount < SS.ServerIPList.size()) {
                final String IP_ = SS.ServerIPList.get(ConnectToIPCount).toString();
                final int Port_ = SS.Port;
                println("Connect>>" + "Trying to connect with " + IP_ + " on Port " + Port_);


                ConnectToIPCount++;

                try {
                    Thread.sleep(5000);
                    MySock = (Socket) AccessController.doPrivileged(new PrivilegedAction() {

                        public Object run() {
                            try {
                                // Start Secure Code

                                if (!isDirectChecked) {
                                    isDirectChecked = true;
                                    Socket tempSock = new Socket(Proxy.NO_PROXY);
                                    tempSock.connect(new InetSocketAddress(IP_, Port_));
                                    return tempSock;

                                } else {
                                    return (new Socket(IP_, Port_));

                                }
                                // End Secure Code
                            } catch (Exception e) {
                                println("Connect Exception>>" + e.toString());
                            }
                            return null;
                        }
                    });
                    if (MySock != null) {

                        SocketStatus.MySock = MySock;
                        SS.isConnected = true;
                        inputStream = new BufferedInputStream(MySock.getInputStream());
                        outputStream = new BufferedOutputStream(MySock.getOutputStream());
                        Utilities.println("Connection established with " + IP_ + " on port " + Port_);

                        if (SocketStatus.EnablePingPong) {
                            if (CheckStatus != null) {
                                CheckStatus.Dispose();
                            }
                            SS.LastMsgTime = new Date();
                            CheckStatus = new CheckConnectionStatus(SS, this);
                            CheckStatus.setName(SS.SocketName + "Connection Status Thread");
                            CheckStatus.start();

                        }
                    }
                } catch (UnknownHostException e) {
                    println("Connect UnknownHostException>>" + e.toString());
                } catch (IOException e) {
                    println("Connect IOException>>" + e.toString());
                } catch (Exception e) {
                    println("Connect Exception>>" + e.toString());
                }
            }

        }
    }

}

public void SendMsg(String sendMsg) {

    if(!Logs.isFinished) {
        try {

            println("SendMsg>>" + sendMsg);

            if (MySock != null && MySock.isConnected()) {
                try {
                    byte[] b = null;
                    b = sendMsg.getBytes();
                    outputStream.write(b, 0, b.length);
                    outputStream.flush();
                } catch (SocketException | SocketTimeoutException e) {
                    if (MySock != null) {
                        MySock.close();
                    }
                    SS.isConnected = false;


                } catch (Exception e) {
                    println("SendMsg Exception>>" + e.toString());

                }

            }


        } catch (Exception e) {
            Log.d("TCP Client SendMsg >>", "Unable To Connect to server");
        }

    }
}


public String ReceiveMsg() {


    String recvMsg = "";

    if(!Logs.isFinished) {

        try {

            byte[] b = new byte[8092 * 6];
            int recvsz = 0;


            if (MySock != null && MySock.isConnected()) {
                recvsz = inputStream.read(b, 0, b.length);
                if (recvsz > 0) {
                    try {
                        byte[] b2 = new byte[recvsz];
                        System.arraycopy(b, 0, b2, 0, b2.length);

                        recvMsg = (new String(b2));
                        if (recvMsg.length() > 0) {
                            SS.LastMsgTime = new Date();
                        }
                    } catch (Exception e) {
                        println("ReceiveMsg Exception>>" + e.toString());
                    }
                }
            }

        } catch (Exception e) {
            if (SS.isConnected) {

                Utilities.handleException(e);

            }
            SS.isConnected = false;
            println("ReceiveMsg Exception>>>" + e.toString());
            Log.d("RESPONSE FROM SERVER", "S: Received Message: '" + e.toString() + "'");

        }
    }

    return recvMsg;
}

public void println(String msg) {
    if (SS.Debug) {
        String strDateFormat1 = "HH:mm:ss";
        SimpleDateFormat sdf1 = new SimpleDateFormat(strDateFormat1);
         Utilities.println(SS.SocketName + " (" + sdf1.format(new Date()) + ") " + msg);
    }
}

private final List<MessageRecieveListner> _listeners = new ArrayList<>();
private final List<MessageRecieveListner> _listenersStrength = new ArrayList<>();

public synchronized void addListener(MessageRecieveListner l) {
   _listeners.add(l);
   _listenersStrength.add(l);
}




private synchronized void _fireMessageEvent(String msg) {
    MessageRecieveEvent MsgEvent = new MessageRecieveEvent(this, msg);
    for (MessageRecieveListner listener : _listeners) {
        listener.MessageRecieved(MsgEvent);

    }
}


public synchronized void _fireStatsEvent(Status status, String msg) {
    MessageRecieveEvent MsgEvent = new MessageRecieveEvent(this, status, msg);

    for (MessageRecieveListner listener : _listeners) {
        listener.ConnectionStatus(MsgEvent);
    }
}

private class DequeueMessageThread implements Runnable {

    public DequeueMessageThread() {
    }

    @Override
    public void run() {
        if(!Logs.isFinished) {
            while (Continue) {
                if (!Queue.isEmpty()) {
                    try {
                        String data = Queue.take().trim();
                        if (SS.MessageParser.length() > 0) {
                            if (data.lastIndexOf(SS.MessageParser) == data.length() - 1) {
                                _fireMessageEvent(tempData + data);
                                tempData = "";
                            } else {
                                if (data.indexOf(SS.MessageParser) > 0) {
                                    String particalCompleteData = tempData + data.substring(0, data.lastIndexOf(SS.MessageParser));
                                    tempData = data.substring(data.lastIndexOf(SS.MessageParser) + 1);
                                    _fireMessageEvent(particalCompleteData);
                                    Utilities.println("incomplete data");
                                }
                            }
                        } else {
                            _fireMessageEvent(data);
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        Continue = false;
                    }
                }

            }
        }
    }
}
java android tcp java-me

评论

0赞 Community 4/16/2022
请修剪您的代码,以便更轻松地找到您的问题。请遵循这些准则,以创建最小的可重现示例
1赞 Stephen C 4/16/2022
我的建议是首先使用 Android 应用程序分析器来确定代码将所有 CPU 时间花费在哪里。正如社区机器人所指出的,问题中的代码太多,无法一一列举。(而且你忽略了标识符的 Java 样式规则,这使得你的代码更难阅读。
1赞 Stephen C 4/16/2022
我注意到你说:“我已经在 android 的分析器中检查过了。这难道没有告诉你问题出在哪里吗?它说了什么?
0赞 Ayesha 4/17/2022
问题是它占用了很高的 CPU 使用率,我想优化它,因为它使应用程序变慢
0赞 user207421 4/17/2022
“which continuous send 'Hello' messages to the server to maintain a client-server connection”:dong 没有这种效果。它只是冒烟CPU。网络和对等方仍然可以随时断开连接。如果你必须这样做,你至少应该将这些消息间隔一段时间,比如 30 秒。 注意不会按照你的想法去做。当连接关闭或重置时,它不会神奇地变成假。Socket.isConnected()

答: 暂无答案