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

ソケットからの読み取りは、ソケットが実際にどこに接続されているか、および反対側がどのように応答するかに応じて、非常に難しい問題です。

反対側が非常に高速な場合は、ソケットに十分なデータを提供できるため、読み取りルーチンが実際に正常に動作します。ただし、反対側に何らかの遅延がある場合 (小さなデフォルト タイムアウトを含む読み取りルーチンよりも遅くする必要があるだけです)、反対側にデータがある可能性があっても、読み取りは失敗します。到着が少し遅すぎます。ソケットで。

必要に応じて、独自の最小タイマーと最大タイマーを読み取りルーチンにラップすることができます。

より詳しい情報を提供してください。問題をよりよく理解することができます。

多くの場合、相手側がデータをソケットにプッシュするのに十分な長さの最小タイムアウトが必要ですが、データが到着するまで実際に待機する最大時間も必要になる場合があります。

アップデート:

最初に監視スレッドを開始するランナブル。必要に応じて、ループ内で使用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 に答える