Witam
Walczyłem dzisiaj z nieblokującą komunikacją. Niestety nie udało mi się spełnić mojego założenia.
Uruchamiam serwer i klienta
- Klient wysyła wiadomość do serwera
- Serwer odbiera wiadomość i odpowiada klientowi
- Klient odbiera wiadomość i odpowiada serwerowi
- No i powrót do punktu 2.
Wszystko ma odbywać się w pętli bez zamykania kanału i ponownego łączenia.
Czy wiecie gdzie popełniłem błąd?
Kod serwera:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
public final class NioServerTest implements ChannelWriter {
private int port = 8080;
private ByteBuffer bb = ByteBuffer.allocate(1000);
public static void main(String[] args) {
NioServerTest server = new NioServerTest();
server.startServer();
}
public void startServer() {
try {
Selector selector = Selector.open();
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
ServerSocket ss = ssc.socket();
ss.bind(new InetSocketAddress(port));
ssc.register(selector, SelectionKey.OP_ACCEPT);
while(true) {
//System.out.println("waiting for client connection");
if(selector.select() > 0) {
performIO(selector);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void performIO(Selector s) {
Iterator<SelectionKey> i = s.selectedKeys().iterator();
while(i.hasNext()) {
try {
SelectionKey sk = i.next();
if(sk.isAcceptable()) {
//System.out.println("accept client connection");
acceptConnection(sk, s);
}else if (sk.isReadable()) {
//System.out.println("read from client");
readWriteClient(sk);
sk.channel().register(s, SelectionKey.OP_READ);
} else if (sk.isWritable()) {
}
}catch (IOException e) {
e.printStackTrace();
}
i.remove();
}
}
public void acceptConnection(SelectionKey sk, Selector s) throws IOException{
ServerSocketChannel server = (ServerSocketChannel) sk.channel();
SocketChannel sChannel = server.accept();
sChannel.configureBlocking(false);
sChannel.register(s, SelectionKey.OP_READ);
}
public void readWriteClient(SelectionKey sk) throws IOException {
SocketChannel schannel = (SocketChannel) sk.channel();
bb.flip();
bb.clear();
int count = schannel.read(bb);
if (count > 0) {
bb.flip();
String input = Charset.forName("UTF-8").decode(bb).toString();
System.out.println(input);
bb.flip();
bb.clear();
bb.put(">>> Odpowiedź serwera".getBytes());
bb.flip();
String inputs = Charset.forName("UTF-8").decode(bb).toString();
System.out.println(inputs);
bb.rewind();
schannel.write(bb);
schannel.register(sk.selector(), SelectionKey.OP_READ);
//schannel.close();
}
}
public void prl(Object o) {
System.out.println(o.toString());
}
}
Kod klienta:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
public final class NioClientTest implements ChannelWriter {
private int port = 8080;
private String hostName = "localhost";
private ByteBuffer bb = ByteBuffer.allocate(1000);
public static void main(String[] args) {
NioClientTest client = new NioClientTest();
client.getResponseFromServer("Wiadomość klienta");
}
//main client method
public void getResponseFromServer(String request) {
try {
//non blocking client socket
SocketChannel sc = SocketChannel.open();
sc.configureBlocking(false);
InetSocketAddress addr = new InetSocketAddress(hostName, port);
sc.connect(addr);
while (!sc.finishConnect()) {
System.out.println("conneting to server");
}
//send request
bb.flip();
bb.clear();
bb.put(request.getBytes());
bb.flip();
sc.write(bb);
//process response
Selector selector = Selector.open();
sc.register(selector, SelectionKey.OP_READ);
while(true) {
if(selector.select() > 0) {
if(processServerResponse(selector)) {
//return;
}
}
}
}catch (IOException e) {
e.printStackTrace();
}
}
public boolean processServerResponse(Selector s) {
Iterator<SelectionKey> i = s.selectedKeys().iterator();
while(i.hasNext()) {
try {
SelectionKey sk = i.next();
if (sk.isReadable()) {
SocketChannel schannel = (SocketChannel) sk.channel();
bb.flip();
bb.clear();
int count = schannel.read(bb);
if (count > 0) {
bb.rewind();
String response =
Charset.forName("UTF-8").decode(bb).toString();
System.out.println("response: "+response);
//schannel.close();
return true;
}
schannel.register(s, SelectionKey.OP_READ);
} else if (sk.isWritable()) {
SocketChannel channel = (SocketChannel) sk.channel();
channel.write(ByteBuffer.wrap("ce".getBytes()));
sk.cancel();
channel.register(s, SelectionKey.OP_READ);
}
i.remove();
}catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
public void prl(Object o) {
System.out.println(o.toString());
}
}
Pozdrawiam