Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/187.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 Android-多线程TCP连接_Java_Android_Multithreading_Tcp_Android Asynctask - Fatal编程技术网

Java Android-多线程TCP连接

Java Android-多线程TCP连接,java,android,multithreading,tcp,android-asynctask,Java,Android,Multithreading,Tcp,Android Asynctask,我一直在寻找我的问题的答案,但到目前为止,没有一个解决方案能帮我解决这个问题。我正在开发一款与另一台服务器设备通信的应用程序。应用程序向服务器发送查询,并接收相应的响应以动态创建片段 在第一个实现中,应用程序发送查询,然后在单个线程中等待接收答案。但该解决方案并不令人满意,因为该应用程序没有收到来自服务器的任何反馈。服务器管理员说他收到了询问,但他暗示设备发回答案的速度太快,而且在收到答案时,应用程序可能还没有听到 因此,我试图实现的是创建单独的线程:一个用于侦听,另一个用于发送查询。侦听程序将

我一直在寻找我的问题的答案,但到目前为止,没有一个解决方案能帮我解决这个问题。我正在开发一款与另一台服务器设备通信的应用程序。应用程序向服务器发送查询,并接收相应的响应以动态创建片段

在第一个实现中,应用程序发送查询,然后在单个线程中等待接收答案。但该解决方案并不令人满意,因为该应用程序没有收到来自服务器的任何反馈。服务器管理员说他收到了询问,但他暗示设备发回答案的速度太快,而且在收到答案时,应用程序可能还没有听到

因此,我试图实现的是创建单独的线程:一个用于侦听,另一个用于发送查询。侦听程序将在我们向服务器发送任何内容之前启动,以确保应用程序不会错过服务器响应

到目前为止,实现这一点还没有成功。我尝试过分别编写和运行可运行类和异步任务,但侦听器从未收到响应,在某些情况下,其中一个线程甚至没有执行。以下是asynctask侦听器的代码:

            @Override
        protected String doInBackground(String... params) {

            int bufferLength = 28;
            String masterIP = "192.168.1.100";

            try {
                Log.i("TCPQuery", "Listening for ReActor answers ...");
                Socket tcpSocket = new Socket();
                SocketAddress socketAddress = new InetSocketAddress(masterIP, 50001);
                try {               
                    tcpSocket.connect(socketAddress);
                    Log.i("TCPQuery", "Is socket connected: " + tcpSocket.isConnected());

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

                while(true){

                    Log.i("TCPQuery", "Listening ...");
                    try{
                        Log.i("TCPQuery", "Waiting for ReActor response ...");
                        byte[] buffer = new byte[bufferLength];
                        tcpSocket.getInputStream().read(buffer);
                        Log.i("TCPQuery", "Received message " + Arrays.toString(buffer) + " from ReActor.");
                    }catch(Exception e){
                        e.printStackTrace();
                        Log.e("TCPQuery", "An error occured receiving the message.");
                    }
                }

            } catch (Exception e) {
                Log.e("TCP", "Error", e);
            }

            return "";
        }
这就是任务的名称:

        if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) {
          listener.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
          sender.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
        }
        else {
          listener.execute();
          sender.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        }

你会如何处理这个问题?如果这段代码不够,我很乐意发布更多。

这是因为Android的
AsyncTask
实际上只有一个线程,不管你创建了多少个线程,所以如果你真的想要两个线程同时运行,我建议你使用标准的Java并发包工具,而不是
AsyncTask
。如前所述:

AsyncTask被设计成一个围绕线程和处理程序的助手类 并且不构成通用线程框架。异步任务 理想情况下,应用于短时间操作(每次几秒钟 大多数。)如果需要让线程长时间运行, 强烈建议您使用 java.util.concurrent pacakge如Executor、ThreadPoolExecutor和 未来任务


看,这是tcp连接。因此,您不必担心数据丢失。这是端口到端口的连接,它从不发送流的结尾(-1)。也许你必须关心阅读功能。因为你不能确定是否收到所有的蒸汽。Tcp读取方法是一个阻塞调用。如果您的读取缓冲区大小小于可用的流大小,则它将阻塞,直到可以完全读取为止。如果您使用的是android设备,可能根据您的设备网络,可用流可能会有所不同。所以你有两个选择, 1) 缓冲区大小应该是动态的。首先,使用is.available()检查可用的输入流大小,并根据此大小创建buf大小。如果可用大小为零,则睡眠一段时间以检查它是否丢失其流可用性。 2) 设置输入流超时。它确实可以工作,因为它读取其可用流并等待超时延迟,如果任何流在超时期间不可用,则会抛出超时异常。
尝试更改您的代码。

我忘了提到运行listener或sender中的一个线程是没有问题的。我也尝试过基本Java线程,但没有成功。您将如何使用标准Java线程来解决这个问题?我刚刚创建了两个线程,每个线程都有连接到服务器的代码,然后我一个接一个地调用它们,但结果如上所述。我有一个服务(在Android 4.1中)有几个线程在运行,它们都运行得很好。在上面的代码中,您没有显示如何发送接收,只显示接收。我不知道你的程序的逻辑,但我建议一个套接字用于发送,另一个用于接收(这意味着在你的设备中也有一个服务器端)。我尝试过类似的方法,但我只使用了一个套接字。基本上,连接是在一个“主”线程中建立的,在套接字启动并运行之后,我分别运行两个独立的线程(使用该套接字的)侦听器和发送器。这种方法似乎可行,但是我还没有机会用实际的设备测试它(它可以用我自己的服务器实现)。如果您对我的解决方案有任何疑问,我将非常感谢您提供更多反馈,但当我有机会用真正的交易测试它时,我将无限期地发布更多信息。到目前为止,谢谢大家!事实证明,这个解决方案与我想象的有所不同。问题实际上并不在构造的线程部分,而在于设备试图重新连接回应用程序,但应用程序没有等待连接的服务器套接字。对“服务器”设备机制的误解。再次感谢大家。“可用流可能因设备网络而异”我认为这是不对的,数据如何因网络而异?对我来说毫无意义。网络与设备类型无关,手机和PC的网络类型相同。看,假设你的总流强度为500。可用流的发送长度永远不相等。它可能在某个时间返回50、100、30,以此类推。因此,如果收到0,则必须等待一段时间并设置读取超时以检查进一步的可用性。如果没有可用的流,它将自动抛出readtimeout异常。我以前遇到过这个问题,我通过这个机制来处理这个问题。试试这个,你的问题一定会得到解决。首先我不是那个问问题的人,其次我从来没有遇到过这个问题。如果您发送500个字节,那么无论源/目标设备是什么,您都将收到500个字节,当然,除非网络断开,在这种情况下,您当然会收到一个异常。