服务器:
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.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
import java.util.Iterator;
public class TrainAgain {
private int port;
private Selector selector;
public TrainAgain(int port) {
this.port = port;
}
public void startServer() {
try {
//open serversocketchannel, bind to port,config non-blocking and register on selector .
selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress("localhost",port));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("listen on port " + port);
while (true) {
//blocking here listening to channel that connected
int r = selector.select();
if (r == 0) {
continue;
}
//after connected, use iterator to scan them all
Iterator<SelectionKey> itr = selector.selectedKeys().iterator();
while (itr.hasNext()) {
SelectionKey key = itr.next();
itr.remove();
if (key.isAcceptable()) {
//channel is ready to accept a new socket channel
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
ssc.configureBlocking(false);
//get the socket channel and registed it to selector;
SocketChannel sc = ssc.accept();
sc.configureBlocking(false);
if (sc == null) {
continue;
}
sc.register(selector, SelectionKey.OP_READ);
System.out.println("connected to a new socket channel :" + sc);
}else if(key.isConnectable()){
((SocketChannel)key.channel()).finishConnect();
} else if (key.isReadable()) {
//channel is ready for reading
SocketChannel sc = (SocketChannel) key.channel();
sc.configureBlocking(false);
ByteBuffer buffer = ByteBuffer.allocate(48);
while (true) {
buffer.clear();
int n = sc.read(buffer);
if (n <= 0) {
break;
}
System.out.println("receive data :" + Arrays.toString(buffer.array())+" from "+sc);
}
buffer = ByteBuffer.wrap("welcome!".getBytes());
buffer.flip();
//I write buffer here
sc.write(buffer);
System.out.println("write data :" + Arrays.toString(buffer.array())+" to "+sc);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
TrainAgain again = new TrainAgain(8000);
again.startServer();
}
}
客户:
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
public class Client {
private void startClient(int port) {
try {
//get socketchannel and connect to server
SocketChannel sc = SocketChannel.open();
sc.connect(new InetSocketAddress("localhost",port));
System.out.println("connect to server from "+sc);
sc.configureBlocking(false);
RandomAccessFile randomAccessFile = new RandomAccessFile("D:\\nio-data.txt","rw");
FileChannel fc = randomAccessFile.getChannel();
//transfer data from filechannel to socketchannel
fc.transferTo(0, randomAccessFile.length(), sc);
ByteBuffer buffer = ByteBuffer.allocate(48);
if(sc.isConnectionPending()){
sc.finishConnect();
}
System.out.println("connect to server from "+sc);
while(true){
buffer.clear();
System.out.println("read data from "+sc);
//blocking here, why can't I read buffer
int r = sc.read(buffer);
if(r <= 0){
break;
}
System.out.println(Arrays.toString(buffer.array()));
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.startClient(8000);
}
}
我是Java NIO的新生,谢谢你的帮助 . 我已经调试了,这是输出:
从服务器:
侦听连接到新套接字通道的端口8000:java.nio.channels.SocketChannel [connected local = / 127.0.0.1:8000 remote = / 127.0.0.1:62694]接收数据:[82,101,116,117, 116,104,101,110,32,105,110,118,111,107,105,110,103,32,116,104,105,115,32,109,101,116,104,111,100,来自java.nio.channels.SocketChannel的32,104,97,115,32,110,111,32,101,102,102,101,96,16,46,0,0,0,0] [connected local = /127.0.0.1:8000 remote = / 127.0.0.1:62694]将数据写入:[119,101,108,99,111,109,101,33]到java.nio.channels.SocketChannel [connected local = / 127.0 . 0.1:8000远程= / 127.0.0.1:62694]
来自客户:
从java.nio.channels.SocketChannel [connected local = / 127.0.0.1:62694 remote = localhost / 127.0.0.1:8000]连接到服务器从java.nio.channels.SocketChannel连接到服务器[connected local = / 127.0 . 0.1:62694 remote = localhost / 127.0.0.1:8000]从java.nio.channels.SocketChannel读取数据[connected local = / 127.0.0.1:62694 remote = localhost / 127.0.0.1:8000]
但最终,客户在 read(buffer) 句子中被阻止了 .
1 回答
我知道了!仔细调试之后,我发现在wrap(bytes)之后,其函数是将零设置为缓冲区的位置,我使用另一个filp方法,其功能是将位置 which is zero now 设置为limit . 所以缓冲区实际上并没有发送给客户端 .