Android Socket tcp连接状态判断 您所在的位置:网站首页 androidsocket连接断开 Android Socket tcp连接状态判断

Android Socket tcp连接状态判断

2023-06-06 22:24| 来源: 网络整理| 查看: 265

Android 实现tcp连接的方式

SocketChannel

AsynchronousSocketChannel

Socket

SocketChannel

SocketChannel是Java NIO库提供的一种通道(Channel)类型,用于基于NIO的网络通信。

SocketChannel提供了非阻塞的I/O操作,可以实现高效的多路复用(Multiplexing)。

它是双向通信的,可以通过read()和write()方法进行读取和写入操作。

在Android中,可以使用SocketChannel来进行网络通信,但需要注意在主线程之外执行,以免阻塞主线程。

select() 方法通常用于服务器端的事件监听,用于监视多个通道的可读、可写等事件状态。对于客户端而言,select()方法不适合用于连接监听,因为客户端通常只需要与单个服务器建立连接,而不需要同时监听多个连接。 socketChannel = SocketChannel.open(); socketChannel.configureBlocking(false);//读写模式。false表示非阻塞,true表示阻塞。 /** * 先注册再连接 */ mSelector = Selector.open(); socketChannel.register(mSelector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); socketChannel.connect(new InetSocketAddress(getIp(),getPort())); int count = mSelector.select(); Log.e(TAG,"count = " + count); AsynchronousSocketChannel

AsynchronousSocketChannel是Java NIO.2引入的异步I/O库中的一部分,用于异步非阻塞的网络通信。

AsynchronousSocketChannel提供了基于回调(Callback)的异步操作,使得在进行网络通信时可以非阻塞地执行其他任务。

它支持读取和写入操作,并提供了read()和write()方法来进行异步操作。

在Android中,可以使用AsynchronousSocketChannel进行异步的网络通信,适用于需要在进行网络操作时不阻塞主线程的场景。

connect() 连接时判断 import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; public class Client { public static void main(String[] args) { try { AsynchronousSocketChannel channel = AsynchronousSocketChannel.open(); channel.connect(new InetSocketAddress("example.com", 8080), null, new CompletionHandler() { @Override public void completed(Void result, Void attachment) { // 连接成功 System.out.println("Connected to the server"); // 执行后续操作 } @Override public void failed(Throwable exc, Void attachment) { // 连接失败 System.out.println("Failed to connect to the server"); // 执行失败处理逻辑 } }); // 可以继续进行其他操作 } catch (IOException e) { e.printStackTrace(); } } } read()判断实时连接状态 import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; public class Client { private static final int BUFFER_SIZE = 1024; public static void main(String[] args) { try { AsynchronousSocketChannel channel = AsynchronousSocketChannel.open(); channel.connect(new InetSocketAddress("example.com", 8080), null, new CompletionHandler() { @Override public void completed(Void result, Void attachment) { System.out.println("Connected to the server"); startReading(channel); // 开始读取服务器数据 // 执行其他操作 } @Override public void failed(Throwable exc, Void attachment) { System.out.println("Failed to connect to the server"); } }); // 阻塞等待连接完成 channel.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } private static void startReading(AsynchronousSocketChannel channel) { ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); channel.read(buffer, null, new CompletionHandler() { @Override public void completed(Integer bytesRead, Void attachment) { if (bytesRead == -1) { // 服务器已经关闭了连接 System.out.println("Server disconnected"); // 执行处理断开连接的逻辑 } else { // 继续读取数据 buffer.flip(); byte[] data = new byte[buffer.remaining()]; buffer.get(data); String receivedData = new String(data); System.out.println("Received data from server: " + receivedData); buffer.clear(); startReading(channel); // 继续读取服务器数据 } } @Override public void failed(Throwable exc, Void attachment) { // 读取操作失败,可以认为服务器已经断开连接 System.out.println("Failed to read data from server: " + exc.getMessage()); // 执行处理断开连接的逻辑 } }); } }

通过不断进行读取操作,客户端可以实时监听到服务器主动断开连接的情况,并执行相应的处理逻辑。

Socket

Socket是Java中经典的Socket类,用于基于传统的阻塞式I/O进行网络通信。

它提供了阻塞式的读取和写入操作,即read()和write()方法。

在Android中,可以使用Socket类进行网络通信,但需要注意在Android的主线程中执行网络操作可能导致阻塞,因此通常建议在子线程中使用Socket类进行网络通信。

read() = -1 int bytesRead = inputStream.read(buffer); if (bytesRead == -1) { // 服务器已经关闭了连接 System.out.println("Server disconnected"); // 执行处理断开连接的逻辑 }

read()是阻塞的,非阻塞模式:将Socket设置为非阻塞模式,可以通过setSoTimeout()方法设置超时时间,然后使用available()方法检查是否有数据可读,再调用read()方法读取数据。

Java NIO(New I/O)中提供了更为灵活的非阻塞I/O操作方式,可以使用Selector、SelectableChannel等类来实现非阻塞的Socket通信。

socket.setSoTimeout(timeout); // 设置超时时间 InputStream inputStream = socket.getInputStream(); while (true) { if (inputStream.available() > 0) { int bytesRead = inputStream.read(buffer); // 处理读取的数据 break; // 退出循环 } else { // 没有数据可读,可以执行其他操作 } }

当read()方法返回-1时,并不一定意味着连接已经断开,可能还存在其他情况。

在Socket编程中,当read()方法返回-1时,表示已经到达流的末尾,即远程服务器已经关闭了连接。这通常是一种常见的情况,可以可靠地判断连接是否已经断开。

还有一些其他情况可能导致read()方法返回-1:

读取超时:如果在设置的超时时间内没有读取到数据,read()方法可能会返回-1。这并不表示连接已经断开,而只是表示在超时时间内没有数据可读。这种情况下,您可以根据具体需求来判断是否认为连接已经断开。

错误发生:在某些错误情况下,read()方法也可能返回-1。例如,网络中断、连接重置等。这时候,read()方法返回-1可能表示连接已经断开,但也可能是由于其他错误导致的。为了确定连接的状态,您可能需要根据具体的错误类型进行额外的处理和判断。

因此,仅仅依靠read()方法返回-1是无法绝对确定连接已经断开的,需要结合其他上下文信息和错误处理来判断连接的状态。

上述适合不停读取消息的场景下判断连接状态

心跳机制

1.sendUrgentData()捕获IO异常,(接收端要处理、过滤1字节消息)

try { mSocket.sendUrgentData(0xFF); } catch (IOException e) { e.printStackTrace(); Log.e(TAG,"tcp HeartbeatThread run error = " + e.toString()); } mOutputStream.write(heartbeatByte); mOutputStream.flush();

SocketChannel和AsynchronousSocketChannel是Java NIO库提供的非阻塞I/O的方式,适用于需要高效、异步的网络通信。而Socket类是传统的阻塞式I/O的方式,适用于简单的网络通信场景。

本文来自博客园,作者:西瓜皮不甜,转载请注明原文链接:https://www.cnblogs.com/Jieth/p/17439780.html



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有