Android,检查套接字是否可以发送消息?

时间:2018-03-14 12:05:01

标签: android sockets

在我的应用中,我有Socket这样:

Socket socket = new Socket();
socket.connect(new InetSocketAddress(ip, port), 5000);
outputStream = new DataOutputStream(socket.getOutputStream());
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));

我这样写socket

outputStream.write((message).getBytes());

从中读出来就像这样:

while (true) {
        try {
            String message = inputStream.readLine();
            if (message != null) {
               //do sth here
            }
        } catch (IOException e) {
            e.printStackTrace();        
        }
}

现在问题是有时互联网连接太慢,连接保持活动状态(套接字保持连接)但无法发送任何消息。在这种情况下,似乎OutputStream保留消息,直到它能够将消息传递给服务器。当插座处于这种状态时,我想知道的是什么?

我也可以这样问这个问题:我如何知道书面信息是否传递给服务器?

请注意,检查设备是否连接到Internet并不会有帮助,因为设备已真正连接但可能连接不良。

1 个答案:

答案 0 :(得分:-1)

  

当套接字处于此状态时,我想知道的是什么?

当客户端没有收到来自服务器的TCP确认时,它进入该状态,因此可以从客户端的传出缓冲区中删除这些数据包。只要缓冲区中有空间,发送就不会阻止调用者。但是一旦缓冲区填满,后续发送就会阻塞调用者,直到缓冲区清除为止。

我知道检测此情况的唯一方法是使用套接字的getChannel()方法访问其基础SocketChannel,然后register()使用Selector来访问它然后可以使用其select()方法监视/查询套接字是否可写(在其传出缓冲区中有空间)。

但是,这只能告诉您套接字是否可以接受至少1个字节的发送而不会阻塞调用者。它不会告诉您是否可以接受给定的消息完全发送,因为缓冲区可能在消息结束之前填满,在这种情况下发送将阻塞,直到缓冲区释放整个消息的空间。

但是,它可以让你监视套接字连接的运行状况,如果你发现由于缓慢/丢失的ack导致发送被阻止太多,你可能只需关闭套接字并重新连接。

  

如何知道书面邮件是否已发送至服务器?

唯一的方法是让服务器在收到客户端的消息后发回自己的消息。