从插座的Andr​​oid阅读挂在第二读取循环 [英] Android reading from Socket hangs on second read loop

查看:178
本文介绍了从插座的Andr​​oid阅读挂在第二读取循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实现我的应用程序聊天。连接到一个服务器使用套接字制成。我要注册到该服务器,服务器将aknowledge与答复。

I got to implement a chat in my application. Connection to a server is made using sockets. I should register to that server and the server will aknowledge that with a reply.

我在一个单一的方法来实现这个,我用的BufferedWriter发送命令,然后开始从输入流中读取数据,直到它告诉我,有没有更多的数据。

I have implemented this in a single method where I send the command using a BufferedWriter, and then start reading from the input stream until it tells me there is no more data.

我正确读取服务器的答复。不过,我从来没有从第二个 in.read 通话负值,因此我的方法挡在了while循环保持(在conditionnal声明,我打电话通知)。

I read properly the server reply. However, I never get the negative value from the second in.read call and thus my method stays blocked in the while loop (in the conditionnal statement where I make that call).

应如何与插座呢?我通常做与文件或其他输入毫无问题流。

如果我只读我应该读取的字节数,这是否意味着我要么必须:

If I should read only the bytes I am supposed to read, does that mean that I either have to:


  • 在事先知道服务器响应的长度?

  • 或使服务器发送一个code,通知它已完成发送它的响应?

目前我做以下内容:

private String sendSocketRequest(String request, boolean skipResponse) throws ChatException {
    if (!isConnected()) openConnection();

    try {
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
                                     socket.getOutputStream()), 2048);
        out.append(request);
        out.flush();
        out = null;
    } catch (IOException e) {
        LogHelper.error("Unable to send socket request: " + request, e);
        throw new ChatException("Unable to send socket request: " + request, e);
    }

    try {
        BufferedReader in = new BufferedReader(new InputStreamReader(
                                     socket.getInputStream()), 2048);
        StringBuffer response = new StringBuffer();
        char[] buffer = new char[2048];
        int charsRead = -1;

// >>>>>>>> This is where it gets blocked <<<<<<<<<

        while ((charsRead = in.read(buffer)) >= 0) {
            if (charsRead > 0) response.append(new String(buffer, 0, charsRead));
        }
        return response.toString();
    } catch (IOException e) {
        LogHelper.error("Unable to read socket response: " + request, e);
        throw new ChatException("Unable to read socket response: " + request, e);
    }
}

连接到服务器与以下方法进行:

Connection to the server is made with the following method:

public synchronized void openConnection() throws ChatException {
    try {
        socket = new Socket(Constants.API_CHAT_SERVER_ADDRESS, Constants.API_CHAT_SERVER_PORT);
        socket.setKeepAlive(true);

        LogHelper.debug("CHAT      >> Connected to the chat server: " + Constants.API_CHAT_SERVER_ADDRESS);
    } catch (UnknownHostException e) {
        LogHelper.error("Unable to open chat connection", e);
        throw new ChatException("Unable to open chat connection", e);
    } catch (IOException e) {
        LogHelper.error("Unable to open chat connection", e);
        throw new ChatException("Unable to open chat connection", e);
    }
}


推荐答案

数据的将被发送的量/通过套接字基于连接接收是协议dependend和不知道的TCP / IP栈,但只应用层

The amount of data to be sent/received over a socket based connection is protocol dependend and not known to the TCP/IP stack, but only to the application layer.

使用的协议是开发商dependend ... ;-)所以来你的问题:

The protocol used is developer dependend ... ;-) so coming to your questions:

如果我只读我应该读取的字节数,这是否意味着我要么必须:

If I should read only the bytes I am supposed to read, does that mean that I either have to:


      
  • 在事先知道服务器响应的长度?

  •   

是的,这是一种可能性。

Yes, this is one possibility.


      
  • 或使服务器发送一个code,通知它已完成发送它的响应?

  •   

也不错,因为这是另一种可能性。常见的标记是 \\ n \\ r \\ n 。在 NUL / '\\ 0'的性格也可能是有意义的。

Also yes, as this is another possibility. Common markers are \n or \r\n. The NUL/'\0' character also might make sense.

第三个选项是preFIX以恒定的数字描述字节来量字节每一个数据块。

A third option is to prefix each data chunk with a constant number of bytes describing the amount of bytes to come.

这篇关于从插座的Andr​​oid阅读挂在第二读取循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆