简体   繁体   中英

Java trouble with SocketChannel connections

This is a class assignment, so I need hints more than answers.

I have a process running on four virtual linux machines. Each process communicates with two of its neighbors. Each process uses

server = ServerSocketChannel.open()
server.configureBlocking(false)
server.socket().bind(new InetSocketAddress(port))
server.register(selector, SelectionKey.OP_ACCEPT)

At startup, process A doesn't try to connect to anyone. Process B does

SocketChannel SC = SocketChannel.open()
SC.configureBlocking( false )
SC.connect(new INetSocketAddress( A-machine, A-port )
SC.register( selector, SC.validOps())

Process C does the same with B; and D with C.

Next, I call selector.select and iterate through any selectedKeys. When I see key.isValid() && key.isAcceptable() both true, I think a socket is attempting to connect to me and I call

SocketChannel client = server.accept()
client.configureBlocking(false)
client.register(selector, client.validOps() )

When I see key.isValid() && key.isConnectable() both true, I think a server is available for me to connect to. I call

SocketChannel connectingChannel = (SocketChannel)key.channel()
connectingChannel.finishConnect()

When I see key.isValid() && key.isReadable(), I read in a message I have received.

This process works AS LONG AS I START THE PROCESSES IN ORDER: A, B, C, D. If I only start B, it fails on the finishConnect statement.

I read the docs where isConnectable tests whether this key's channel has either finished, or failed to finish, its socket-connection operation. How can isConnectable be true and I get a failure on finishConnect?

We wrapped a try/catch around the finishConnect. Inside the catch, we called cancel on the current SelectionKey, then called the method that had attempted the connect (the second snippet in the original problem description):

SocketChannel SC = SocketChannel.open()
SC.configureBlocking( false )
SC.connect(new INetSocketAddress( A-machine, A-port )
SC.register( selector, SC.validOps())

Anticipating that we would have to do this, we added code to store a relationship between SC and A-machine and A-port, so we would have them when we did the retry. So, in the catch, before the cancel, we used the failing SocketChannel to look up the necessary A-machine and A-port data we were going to need.

Eventually, then, the server came up and this connection was made successfully.

I know this is an answer, not a hint, but it was our assignment :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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