0

我有一个 BufferedReader,当我尝试阅读它时,它只是挂起并且什么都不做,我这样做对吗?我在 AsyncTask 中使用它。

  • 编辑:我有一个连接到 Wi-Fi 的平板电脑,它连接到我的计算机,它在端口 5334 上的 172.20.104.203 上广播,我可以看到线程何时启动,但之后什么也没有。

这是我的代码:

try {
       final BufferedReader in = new BufferedReader(
       new InputStreamReader(socket.getInputStream()));       
       String line = null;
       while ((line = in.readLine()) != null) {
          final String msg;
          msg = (line);
          Log.d("DeviceActivity", msg);
       }
    } catch (Exception e) {
        e.printStackTrace();
        Log.e("ClientAcivtity: Exception",
        String.valueOf(e));
    }
  • 编辑 我拥有所有正确的权限或任何东西,我在 AsyncTask 之外执行此操作,它运行良好,移动它是因为我不希望它在主线程中。

-编辑,这是完整的代码。

public class NetworkTask extends AsyncTask<Void, byte[], Boolean> {
        Socket nsocket; // Network Socket
        InputStream nis; // Network Input Stream
        OutputStream nos; // Network Output Stream
        private Handler handler = new Handler();

        Boolean connected = false;

        public static final int PORT = 5334;
        public String SERVERIP = "172.20.104.203";

        Socket socket;

        @Override
        protected void onPreExecute() {
            Log.i("AsyncTask", "onPreExecute");
            InetAddress serverAddr;
            try {
                serverAddr = InetAddress.getByName(SERVERIP);
                socket = new Socket(serverAddr, PORT);
                connected = true;
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                Log.e("ClientAcivtity: Exception", String.valueOf(e));
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                Log.e("ClientAcivtity: Exception", String.valueOf(e));
            }
        }

        @Override
        protected Boolean doInBackground(Void... params) { // This runs on a
                                                            // different thread
            boolean result = false;

            try {

                Log.d("ClientActivity", "C: Connecting...");
                if (socket != null) {
                    int cont = 1;
                    while (cont == 1) {
                        try {
                            Log.d("ClientActivity", "C: Sending command.");
                            PrintWriter out = new PrintWriter(
                                    new BufferedWriter(new OutputStreamWriter(
                                            socket.getOutputStream())), true);
                            // where you issue the commands
                            out.println("getPos");
                            Log.d("ClientActivity", "C: Sent " + "getPos");

                        } catch (Exception e) {
                            Log.e("ClientAcivtity: Exception",
                                    String.valueOf(e));
                        }
                        try {
                            final BufferedReader in = new BufferedReader(
                                    new InputStreamReader(
                                            socket.getInputStream()));
                            String line = null;
                            while ((line = in.readLine()) != null) {
                                final String msg;
                                msg = (line);
                                Log.d("DeviceActivity", msg);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            Log.e("ClientAcivtity: Exception",
                                    String.valueOf(e));
                        }
                        cont--;
                    }

                    Log.d("ClientActivity", "C: Closed.");
                }
            } catch (Exception e) {
                Log.e("ClientAcivtity: Exception", String.valueOf(e));
            }

            return result;
        }

        @Override
        protected void onProgressUpdate(byte[]... values) {
            if (values.length > 0) {
                Log.i("AsyncTask", "onProgressUpdate: " + values[0].length
                        + " bytes received.");
            }
        }

        @Override
        protected void onCancelled() {
            Log.i("AsyncTask", "Cancelled.");
        }

        @Override
        protected void onPostExecute(Boolean result) {
            if (socket != null) {
                if (connected) {
                    if (result) {
                        Log.i("AsyncTask",
                                "onPostExecute: Completed with an Error.");
                        try {
                            socket.close();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    } else {
                        Log.i("AsyncTask", "onPostExecute: Completed.");
                        try {
                            socket.close();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
4

3 回答 3

0

尝试这样做:

final BufferedReader in = new BufferedReader(new InputStreamReader(
                                                    socket.getInputStream()));
StringBuffer buf = new StringBuffer();
int i;
while((i = in.read()) != -1){
    buf.append((char) i);
}

String data = buf.toString();
于 2012-04-16T20:52:45.660 回答
0

从套接字读取是一个相当困难的问题,具体取决于套接字实际连接到的位置以及另一端如何响应。

如果另一端的速度非常快,它可以为套接字提供足够的数据,以便读取例程实际上可以正常工作。但是,如果另一端有任何类型的延迟(只需要比您的读取例程慢,包括小的默认超时),那么即使另一端可能有数据,您的读取也会失败 - 只是到达有点太慢了在插座上。

根据您的需要,您可以将自己的最小和最大计时器包装在读取例程中。

请提供更多信息,我们可以更好地理解这个问题。

在许多情况下,需要有一个足够大的最小超时时间,以便另一方将数据推送到套接字——但您可能还需要一个最大时间来确定您实际希望等待数据到达的时间。

更新:

首先是runnable来启动监控线程。如果需要,您可以monitoringCanRun在循环中使用来中断线程。并且monitoringThreadIsAlive可以用来知道线程是否还在运行。

    monitoringCanRun = true;
    new Thread(new Runnable() {
    public void run() {
        monitoringThreadIsAlive = true;
        performMonitoring();
        monitoringThreadIsAlive = false;
    }
    }).start();
}

和 performMonitoring 看起来像:

   public void performMonitoring() {
while (monitoringCanRun) {
   ... do your read in the while loop
    ...you might like to insert some delay before trying again...
    try { //we delay every partial read so we are not too fast for the other side
    Thread.sleep(100);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
}

}
于 2012-04-16T20:57:09.943 回答
0

我的猜测是,当您写出命令“getPos”时,底层 BufferedWriter 实际上并没有在线发送数据(您应该使用 tcpdump/wireshark 验证这一点)。如果是这种情况,服务器不会响应 readLine(),因为它从未收到命令。要验证此声明,请在out.flush();之后添加out.println("getPos");

真的,tcpdump 可能会给你一个比论坛上任何人更好的答案。

另请参阅http://developer.android.com/reference/java/io/BufferedWriter.html

于 2012-04-16T21:36:53.537 回答