NIO 关于SocketChannel的isConnected与finishConnect区别

9 篇文章 0 订阅

-----重要的先说-----

区别:

1、isConnected是判断是否连接成功的,如果连接成功,则true,否则false;源码如下:

通过上面两张图能够知道,isConnected只有当状态为2(已连接时)才会返回true。

2、finishConnect是判断连接是否完成

(看起来和isConnected一样,但是,finishConnect内部会主动抛异常,isConnected则不会【线程中断异常那不算】)

请看源码,然后慢慢解释

如果已连接(状态为2),则true;否则,如果不处于已连接状态,并且不是正在连接(pending),就会抛异常,然后其他情况旧放那会false

 

下面是我看到令我得到以上结果的一篇博客的片段。。。令我恍然大悟的。

来自https://blog.csdn.net/billluffy/article/details/78036998

connect事件(连接--成功or失败?)

在之前的Socket通道中,已经看到,非阻塞模式下,connect操作会返回false,后面会发出CONNECT事件来表示连接,但是这里其实没有区分成功还是失败。。

 

connect事件:表示连接通道连接就绪或者发生了错误,会被加到ready 集合中(下面面是API说明)

If the selector detects that the corresponding socket channel is ready to complete its connection sequence, or has an error pending, then it will add OP_CONNECT to the key's ready set and add the key to its selected-key set.

 

所以这个事件发生的时候不能简单呢的认为连接成功,要使用finishConnect判断下,如果连接失败,会抛出异常

NIO就绪处理之OP_CONNECT
 

1if (key.isValid() && key.isConnectable()) { 

2    SocketChannel ch = (SocketChannel) key.channel(); 

3    if (ch.finishConnect()) { 

4        // Connect successfully 

5        // key.interestOps(SelectionKey.OP_READ); 

6    } else { 

7        // Connect failed 

8    } 

9}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: NioSocketChannel类本身并没有实现Serializable接口,也就是说它本身不能被序列化。如果你想将NioSocketChannel对象序列化,你需要自己定义一个类来实现Serializable接口,并将NioSocketChannel对象作为该类的一个成员变量。然后你就可以将这个自定义类的对象序列化了。 具体实现方式可以参考如下代码: ``` import java.io.Serializable; public class MyClass implements Serializable { private NioSocketChannel socketChannel; public MyClass(NioSocketChannel socketChannel) { this.socketChannel = socketChannel; } public NioSocketChannel getSocketChannel() { return socketChannel; } public void setSocketChannel(NioSocketChannel socketChannel) { this.socketChannel = socketChannel; } } ``` 这样你就可以通过如下代码将MyClass对象序列化: ``` MyClass myObject = new MyClass(socketChannel); // 将myObject对象序列化到文件中 FileOutputStream fos = new FileOutputStream("myObject.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(myObject); oos.close(); ``` ### 回答2: Netty的NioSocketChannel对象是一个网络套接字通道,用于在Java NIO(非阻塞I/O)中进行网络通信。NioSocketChannel类本身并没有直接实现Serializable接口,因为它不是一个可序列化的对象。 Serializable接口是一个标记接口,用于指示一个类可以被序列化,即可以将其转换为字节流以便在网络中传输或持久化到存储设备中。可序列化对象需要实现Serializable接口,并提供相应的序列化和反序列化方法。 然而,NioSocketChannel是Netty的抽象类实现之一,它的子类AbstractChannel已经实现了Serializable接口。可以通过自定义一个类继承NioSocketChannel,并实现Serializable接口来实现将NioSocketChannel对象序列化。 以下是一个可能的示例代码: ```java import io.netty.channel.socket.nio.NioSocketChannel; import java.io.Serializable; public class SerializableNioSocketChannel extends NioSocketChannel implements Serializable { // 添加一个默认的构造函数 public SerializableNioSocketChannel() { super(); } } ``` 在上述示例中,我们创建了一个新的类SerializableNioSocketChannel,该类继承了NioSocketChannel并实现了Serializable接口。通过将NioSocketChannel对象转换为SerializableNioSocketChannel对象,就可以实现对NioSocketChannel对象的序列化。 需要注意的是,由于NioSocketChannel作为网络套接字通道,它包含了底层网络连接状态等非序列化的信息,因此在实际使用中,可能需要根据具体需求选择序列化对象中需要保留的属性。 ### 回答3: Netty的NioSocketChannel对象不能直接实现Serializable接口,因为NioSocketChannel类并没有实现Serializable接口。Serializable接口是Java提供的一种机制,用于将对象转换为字节流,以便能够在网络中传输或持久化到磁盘。 然而,我们可以通过一些其他方式来实现将NioSocketChannel对象序列化和反序列化。比如,可以通过将NioSocketChannel的一些关键信息提取出来,例如远程地址、本地地址、管道选项等,并将这些信息进行序列化和反序列化。 具体实现方式如下: 1. 创建一个包含NioSocketChannel关键信息的可序列化类,例如NioSocketChannelWrapper。 2. 在NioSocketChannelWrapper中定义所需的关键信息字段,例如remoteAddress、localAddress、channelOptions等。 3. 实现NioSocketChannelWrapper类的序列化接口Serializable,并添加序列化和反序列化方法。 4. 在需要将NioSocketChannel对象序列化时,通过构建NioSocketChannelWrapper对象,并将关键信息赋值给NioSocketChannelWrapper的相应字段。 5. 将NioSocketChannelWrapper对象进行序列化处理,并传输到目标。 6. 在需要反序列化NioSocketChannel对象时,接收到NioSocketChannelWrapper对象后,进行反序列化操作,将关键信息提取出来。 7. 通过Netty的Bootstrap或其他相关类,使用提取出的关键信息重新构建NioSocketChannel对象。 需要注意的是,反序列化后的NioSocketChannel对象并不是原始NioSocketChannel对象的完全克隆,而是通过关键信息重新构建的新对象。一些与网络连接、管道状态等相关的信息可能无法被序列化和恢复。 总之,Netty的NioSocketChannel对象不能直接实现Serializable接口,但通过提取关键信息并自定义可序列化类,我们可以实现将NioSocketChannel对象进行序列化和反序列化操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值