Я уже некоторое время пытаюсь работать с NIO SocketChannels, и я в тупик, когда пишу в SocketChannel.Следующий код от моего клиента:
public class nbClient {
/**
* @param args
*/
static int id;
static int delay = 1000;
static int port;
public static void main(String[] args) throws Exception{
if (args.length > 0){
id = Integer.parseInt(args[0]);
port = Integer.parseInt(args[1]);
}
else{
id = 99;
port = 4444;
}
// Create client SocketChannel
SocketChannel client = SocketChannel.open();
// nonblocking I/O
client.configureBlocking(false);
// Connection to host port 8000
client.connect(new java.net.InetSocketAddress("localhost",port));
// Create selector
Selector selector = Selector.open();
//SelectionKey clientKey = client.register(selector, SelectionKey.OP_CONNECT);
SelectionKey clientKey = client.register(selector, client.validOps());
// Waiting for the connection
while (selector.select(1000) > 0) {
// Get keys
Set keys = selector.selectedKeys();
Iterator i = keys.iterator();
// For each key...
while (i.hasNext()) {
SelectionKey key = (SelectionKey)i.next();
// Remove the current key
i.remove();
// Get the socket channel held by the key
SocketChannel channel = (SocketChannel)key.channel();
// Attempt a connection
if (key.isConnectable()) {
// Connection OK
System.out.println("Server Found");
// Close pendency connections
if (channel.isConnectionPending())
channel.finishConnect();
//channel.close();
channel.register(selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ);
}
if (key.isWritable()){
System.out.println("Ready for writing");
// Write on the buffer
ByteBuffer buffer = null;
int counter = 0;
buffer =
ByteBuffer.wrap(
new String(" This is a very long message from Client " + id + " that should exceed the bufer by a bit").getBytes());
int outBytes = channel.write(buffer);
System.out.println(channel.isConnectionPending());
System.out.println(outBytes);
buffer.clear();
counter++;
}
if (key.isReadable()){
System.out.println("Ready for reading");
}
}
}
}
}
Моя проблема связана с попыткой записи на канал.Всякий раз, когда эта часть кода выполняется, она многократно повторяется, записывая данные во время каждой итерации, не дожидаясь, пока сервер ее обработает.Когда я запускаю отладчик с моим кодом, сервер, похоже, может перехватить и обработать передачу (клиент продолжает пересылать запросы, но, по крайней мере, сервер отображает переданные байты).Когда код просто запускается как есть без каких-либо принудительных задержек, клиентский код запускается пару десятков раз, после чего соединение прерывается, а сервер, по-видимому, игнорирует передачу.Вот мой раздел кода сервера - обратите внимание, что он запускается из класса Runnable:
try {
readwriteSelector.select();
// Once the event occurs, get keys
Set<SelectionKey> keys = readwriteSelector.selectedKeys();
Iterator<SelectionKey> i = keys.iterator();
// For each keys...
while(i.hasNext()) {
// Get this most recent key
SelectionKey key = i.next();
if (key.isReadable()){
System.out.println("Is Readable");
}
if (key.isWritable()){
System.out.println("Is Writable");
SocketChannel client = (SocketChannel) key.channel();
buf.clear();
int numBytesRead = client.read(buf);
if (numBytesRead == -1){
client.close();
}
else {
buf.flip();
byte[] tempb = new byte[buf.remaining()];
buf.get(tempb);
String s = new String(tempb);
System.out.println(s);
}
}
// Remove the current key
i.remove();
//readwriteSelector.selectedKeys().clear();
}
} catch (IOException e) {
e.printStackTrace();
}
Я знаю, что это хороший код, но на данный момент я не могу точно определить, где проблема.Может кто-нибудь понять, почему клиент и сервер, по-видимому, не могут общаться, несмотря на тот факт, что передача происходит нормально, если я задерживаюсь?
Спасибо.