【问题标题】:InputStream is not working properlyInputStream 无法正常工作
【发布时间】:2016-12-21 01:48:22
【问题描述】:

我是安卓初学者。我正在尝试处理套接字。但是我的InputStream 没有按预期读取数据。在j = inputStream.read(arrayOfByte, 0, i);之后它正在退出方法请帮助我。

public void readinputstreamforid(final String ip, final int port){
    AsyncTask asyncTask = new AsyncTask() {

        @Override
        protected Object doInBackground(Object[] objects) {

            try {
                socket=new Socket(ip,port);
            } catch (IOException e) {
                e.printStackTrace();
            }
            final byte[] arrayOfByte = new byte[10000];

            InputStream inputStream = null;
            try {
                inputStream = socket.getInputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }

            while (socket.isConnected()) {
                int j = 0;
                int i = arrayOfByte.length;
                try {
                    j = inputStream.read(arrayOfByte, 0, i);
                    if (j == -1)
                        throw new IOException("not working");
                    if (j == 0)
                        continue;
                } catch (IOException e) {
                    e.printStackTrace();
                }
                final String strData = new String(arrayOfByte, 0, j).replace("\r", "").replace("\n", "");
                Log.d("hello","recieved: "+strData);

            }
            try {
                IOUtils.write("!#@\n",socket.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    };

    asyncTask.execute();
}

【问题讨论】:

  • 如果发生错误,您正在记录它,但是您继续执行代码,然后可能会发生更多错误。发生错误时,停止并退出该功能。此外,您正在尝试在套接字断开连接后写入套接字的OutputStream。你真的想用这段代码完成什么?您要处理什么样的数据?看起来您正在尝试阅读文本行。将InputStream 包裹在BufferedReader 中,然后您可以在循环中使用它的readLine() 方法。
  • InputStream.read() 在到达流的末尾时返回 -1。对于套接字,这意味着连接关闭时。这不是错误条件,所以不要抛出异常。打破循环。
  • 感谢您的建议。但是当检查断点时,它既没有进入if (j == -1),也没有给出任何错误。而且我也听从了你不抛出异常的建议,但它没有奏效。并且通过调试它显示套接字在读取时没有关闭。请帮助我。 @RemyLebeau
  • 它既没有进入 if (j == -1) 也没有给出任何错误” - 这在物理上是不可能的。 read() 抛出异常(您正在捕获但随后丢弃),或者它返回 if 然后评估的值。
  • j == 0 表示您有一个错误:您为read() 提供了零长度。 continue 是一种奇怪的处理方式。你的尝试捕捉很差。取决于先前try 块中代码成功的代码应该在该try 块内。不要写这样的代码。

标签: java android sockets inputstream


【解决方案1】:

如果发生错误,您正在记录它,但随后您继续执行代码,然后可能会发生更多错误。当发生错误时,STOP 循环并退出函数。 InputStream.read() 在到达流的末尾时返回 -1。对于套接字,这意味着连接关闭时。这并不是真正的错误情况,因此您不需要抛出异常。只是打破循环。您可以将InputStream 包装在BufferedReader 内,这样您就可以使用它的readLine() 方法而不是手动读取字节。

另外,您正在尝试写入套接字的OutputStream 套接字已经断开连接之后。那永远都行不通。

试试这样的:

public void readinputstreamforid(final String ip, final int port){
    AsyncTask asyncTask = new AsyncTask() {

        @Override
        protected Object doInBackground(Object[] objects) {

            try {
                socket = new Socket(ip, port);

                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
                OutputDataStream out = socket.getOutputStream();

                do {
                    String data = in.readLine();
                    if (data == null)
                        break;

                    Log.d("hello", data);
                    IOUtils.write("!#@\n", out, StandardCharsets.UTF_8);
                }
                while (true);

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

            return null;
        }
    };

    asyncTask.execute();
}

【讨论】:

  • 感谢您的建议,但它不起作用.... 在String data = in.readLine(); 之后它正在退出该方法,但应用程序正在运行而没有崩溃。数据在ASCII 字符集中,所以我将StandardCharsets.UTF_8 更改为"ASCII"。这样会有什么问题吗?
  • UTF-8 与 ASCII 100% 兼容,但您可以根据需要使用 StandardCharsets.US_ASCII。至于失败,则需要更具体。 “摆脱方法”实际上是什么意思?方法要么流到末尾并隐式退出,要么显式返回,要么抛出异常。在你的情况下实际发生了什么?而且您从未解释过发送给您的套接字数据实际上是什么样的。它实际上是换行符分隔,还是别的什么?您几乎没有提供有关您的情况的详细信息。
  • 发送!#@\n后的预期数据为*.%$n!D7a*e#。我正在开发一个应用程序来控制我的Arduino。它是换行符分隔的。该方法由片段调用,并写入服务内部。我是android新手,所以请帮助我。
  • @krishna 以及 实际 问题是什么? “摆脱方法”不是描述性的。 Arduino 是否希望您先发送一些东西然后它会回复?因为你的代码是相反的,它期望 Arduino 先发送一些东西然后你回复。
  • 非常感谢,它现在可以工作了....我想如果我开始连续读取输入流,那么我可以随时通过发送输出流来获取数据以获得回复。我使用相同的方式在点击事件中读取数据。它在那里工作。你能解释一下为什么错了吗?
猜你喜欢
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
  • 2016-09-01
  • 2012-07-11
  • 2018-04-08
  • 2017-04-20
  • 2018-10-02
  • 2016-09-04
相关资源
最近更新 更多