Mindaugas Varkalys :
I have simple Server and Client built using Java NIO sockets. The idea is that the client sends 5
to server and the server replies with 1
. Then, the client sends 1
again using the same socket and the server should reply with 5
again.
However, the server does not receive the second message. Here is my implementation:
Server.java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
public class Server {
public static void main(String[] args) throws IOException {
Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.bind(new InetSocketAddress(4444));
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
if (selector.select() > 0) {
for (SelectionKey key : selector.selectedKeys()) {
if (key.isReadable()) {
SocketChannel clientChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1);
clientChannel.read(buffer);
System.out.println("Received: " + buffer.array()[0]);
clientChannel.write(ByteBuffer.wrap(new byte[]{1}));
System.out.println("Replied: 1");
}
if (key.isAcceptable()) {
SocketChannel channel = serverChannel.accept();
if (channel != null) {
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
System.out.println("Accepted");
}
}
}
}
}
}
}
Client.java
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
public class Client {
public static void main(String[] args) throws IOException {
Selector selector = Selector.open();
SocketChannel sc = SocketChannel.open();
sc.configureBlocking(false);
sc.connect(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 4444));
sc.register(selector, SelectionKey.OP_CONNECT);
while (true) {
if (selector.select() > 0) {
for (SelectionKey key : selector.selectedKeys()) {
SocketChannel channel = (SocketChannel) key.channel();
if (key.isConnectable()) {
while (channel.isConnectionPending()) {
channel.finishConnect();
}
key.interestOps(SelectionKey.OP_WRITE);
System.out.println("Connected");
}
if (key.isWritable()) {
channel.write(ByteBuffer.wrap(new byte[] { 5 }));
key.interestOps(SelectionKey.OP_READ);
System.out.println("Sending: 5");
}
if (key.isReadable()) {
ByteBuffer buffer = ByteBuffer.allocate(1);
channel.read(buffer);
System.out.println("Received: " + buffer.array()[0]);
key.interestOps(SelectionKey.OP_WRITE);
}
}
}
}
}
}
Server ouput
Accepted
Received: 5
Replied: 1
Client output
Connected
Sending: 5
Received: 1
Sending: 5
Mindaugas Varkalys :
I found a solution to my problem here: https://stackoverflow.com/a/9940133/4167198
select()
returns the number of keys that have changed. So if a key was already ready before theselect()
call then it could return 0 butselectedKeys
could be non-empty.
So checking if select()
returns more than 0 is not necessary.
Server.java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
public class Server {
public static void main(String[] args) throws IOException {
Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.bind(new InetSocketAddress(4444));
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
selector.select();
for (SelectionKey key : selector.selectedKeys()) {
if (key.isReadable()) {
SocketChannel clientChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1);
clientChannel.read(buffer);
System.out.println("Received: " + buffer.array()[0]);
clientChannel.write(ByteBuffer.wrap(new byte[]{1}));
System.out.println("Replied: 1");
}
if (key.isAcceptable()) {
SocketChannel channel = serverChannel.accept();
if (channel != null) {
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
System.out.println("Accepted");
}
}
}
}
}
}
Client.java
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
public class Client {
public static void main(String[] args) throws IOException {
Selector selector = Selector.open();
SocketChannel sc = SocketChannel.open();
sc.configureBlocking(false);
sc.connect(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 4444));
sc.register(selector, SelectionKey.OP_CONNECT);
while (true) {
selector.select();
for (SelectionKey key : selector.selectedKeys()) {
SocketChannel channel = (SocketChannel) key.channel();
if (key.isConnectable()) {
while (channel.isConnectionPending()) {
channel.finishConnect();
}
key.interestOps(SelectionKey.OP_WRITE);
System.out.println("Connected");
}
if (key.isWritable()) {
channel.write(ByteBuffer.wrap(new byte[] { 5 }));
key.interestOps(SelectionKey.OP_READ);
System.out.println("Sending: 5");
}
if (key.isReadable()) {
ByteBuffer buffer = ByteBuffer.allocate(1);
channel.read(buffer);
System.out.println("Received: " + buffer.array()[0]);
key.interestOps(SelectionKey.OP_WRITE);
}
}
}
}
}
Guess you like
Origin http://43.154.161.224:23101/article/api/json?id=356572&siteId=1