In short, no. available() not reliable (at least it was not for me). I recommend using java.nio.channels.SocketChannel associated with Selector and SelectionKey . This solution is somewhat event-based, but more complex than simple sockets.
For clients:
- Make a channel for the socket (
socket ), open the selector ( selector = Selector.open(); ). - Use non-blocking
socket.configureBlocking(false); - Register selector for
socket.register(selector, SelectionKey.OP_CONNECT); connections socket.register(selector, SelectionKey.OP_CONNECT); - Connect
socket.connect(new InetSocketAddress(host, port)); - See if there is anything new
selector.select(); - If βnewβ refers to a successful connection, register the selector for
OP_READ ; if "new" refers to the data available, just read from the socket.
However, in order to have an asynchronous interface, you will need to configure a separate thread (although the socket is created as unlocked, the thread will still block), which checks if something has arrived or not.
There is ServerSocketChannel for the servers, and you use OP_ACCEPT for it.
For reference, this is my code (client), should give you a hint:
private Thread readingThread = new ListeningThread(); private class ListeningThread extends Thread { public void run() { running = true; try { while(!close) listen(); messenger.close(); } catch(ConnectException ce) { doNotifyConnectionFailed(ce); } catch(Exception e) {
And for the server:
public ChannelMessageServer(int port) throws IOException { this.server = ServerSocketChannel.open(); this.server.configureBlocking(false); this.server.socket().bind(new InetSocketAddress(port)); this.server.register(this.selector, SelectionKey.OP_ACCEPT); } protected void listen() throws IOException {
Hope this helps.
source share