这是一个课堂作业,所以我需要提示而不是答案。
我有一个在四台虚拟linux机器上运行的进程。每个进程与其两个邻居通信。每个流程都使用
server = ServerSocketChannel.open()
server.configureBlocking(false)
server.socket().bind(new InetSocketAddress(port))
server.register(selector, SelectionKey.OP_ACCEPT)
启动时,进程A不会尝试连接任何人。流程B
SocketChannel SC = SocketChannel.open()
SC.configureBlocking( false )
SC.connect(new INetSocketAddress( A-machine, A-port )
SC.register( selector, SC.validOps())
过程C对B做同样的事情;和D与C。
接下来,我调用selector.select并遍历任何selectedKeys。当我看到key.isValid()&& key.isAcceptable()都是true,我认为套接字试图连接到我,我打电话给
SocketChannel client = server.accept()
client.configureBlocking(false)
client.register(selector, client.validOps() )
当我看到key.isValid()&& key.isConnectable()都是true,我认为服务器可供我连接。我打电话给
SocketChannel connectingChannel = (SocketChannel)key.channel()
connectingChannel.finishConnect()
当我看到key.isValid()&& key.isReadable(),我读了一封收到的消息。
当我开始按顺序启动过程时,此过程可以正常工作:A,B,C,D。如果我只启动B,则在finishConnect语句中失败。
我读了一些文档,其中isConnectable测试此密钥的通道是否已完成或未能完成其套接字连接操作。怎么可以连接成为真,我在finishConnect上失败了?
答案 0 :(得分:0)
我们在finishConnect周围包裹了一个try / catch。在catch中,我们在当前SelectionKey上调用cancel,然后调用尝试连接的方法(原始问题描述中的第二个片段):
SocketChannel SC = SocketChannel.open()
SC.configureBlocking( false )
SC.connect(new INetSocketAddress( A-machine, A-port )
SC.register( selector, SC.validOps())
预计我们必须这样做,我们添加了代码来存储SC与A-machine和A-port之间的关系,所以当我们进行重试时我们会有它们。因此,在catch中,在取消之前,我们使用失败的SocketChannel来查找我们将需要的必要的A-machine和A-port数据。
然后,最终,服务器启动并且此连接成功。
我知道这是一个答案,而不是一个提示,但这是我们的任务:)