繁体   English   中英

从Socket读取的Android在第二个读取循环中挂起

[英]Android reading from Socket hangs on second read loop

我必须在我的应用程序中实现聊天。 使用套接字连接到服务器。 我应该注册到该服务器,服务器将通过回复知道。

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

我正确阅读了服务器回复。 但是,我从来没有从第二个in.read调用中得到负值,因此我的方法在while循环中被阻塞(在我调用的条件语句中)。

如何用套接字完成? 我通常使用文件或其他输入流没有问题。

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

  • 事先知道服务器响应的长度?
  • 或者让服务器发送代码通知它已完成发送响应?

目前我正在做以下事情:

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);
    }
}

使用以下方法连接到服务器:

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);
    }
}

通过基于套接字的连接发送/接收的数据量是协议依赖的,并且TCP / IP堆栈不知道,但仅限于应用层。

使用的协议是开发人员dependend ... ;-)所以提出你的问题:

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

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

是的,这是一种可能性。

  • 或者让服务器发送代码通知它已完成发送响应?

也是,因为这是另一种可能性。 常用标记是\\n\\r\\n NUL / '\\0'字符也可能有意义。

第三种选择是为每个数据块添加一个恒定数量的字节,用于描述要来的字节数。

也许它更简单地处理ad-hoc类的实例,比如 - 例如 - Message类:而不是处理字节。

服务器:

// Streams
protected ObjectInputStream fromBuffer = null;
protected ObjectOutputStream toBuffer = null;

// Listening for a new connection
ServerSocket serverConn = new ServerSocket(TCP_PORT);
socket = serverConn.accept();
toBuffer = new ObjectOutputStream(socket.getOutputStream());
fromBuffer = new ObjectInputStream(socket.getInputStream());

// Receiving a new Message object
Message data = (Message)fromBuffer.readObject();

客户端然后简单地发送消息:

// Sending a message
Message data = new Message("Hello");
toBuffer.writeObject(data);

只要其成员实现Serializable接口, 消息就可以根据需要复杂

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM