50,559
社区成员
发帖
与我相关
我的任务
分享
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package testsocketchannel;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author root
*/
public class Main implements Runnable {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws IOException, InterruptedException {
// TODO code application logic here
//启动 serversockechannel
Main main=new Main();
Thread t=new Thread(main);
t.start();
//休眠,防止server没有及时启动
Thread.sleep(1000);
//连接server 发送消息
String mes="send a message";
Socket s=new Socket("127.0.0.1", 9000);
OutputStream os=s.getOutputStream();
os.write(mes.getBytes());
os.flush();
os.close();
s.close();
}
//start server
public void run(){
try {
Selector selector;
ServerSocketChannel ssc;
SocketChannel sc;
boolean stop = true;
System.out.println("invoke startServer---------------------");
int nKeys = 0;
selector = Selector.open(); // 打开一个选择器
ssc = ServerSocketChannel.open(); //打开服务器套接字通道。
InetSocketAddress add = new InetSocketAddress(9000);
ssc.socket().bind(add);
ssc.configureBlocking(false); //调整此通道的阻塞模式 true为阻塞 false为非阻塞
SelectionKey seletK = ssc.register(selector, SelectionKey.OP_ACCEPT); //向给定的选择器注册此通道,返回一个选择键。
while (stop) {
synchronized (this) {
nKeys = selector.select(); //选择一组键,其相应的通道已为 I/O 操作准备就绪。返回已更新其准备就绪操作集的键的数目、
System.out.println("nKeys=" + nKeys);
if (nKeys > 0) {
Set<SelectionKey> selectedKeys = selector.selectedKeys(); //返回此选择器的已选择键集。
Iterator i = selectedKeys.iterator(); //返回在此 set 中的元素上进行迭代的迭代器
while (i.hasNext()) {
//如果仍有元素可以迭代,则返回 true
seletK = (SelectionKey) i.next(); //返回迭代的下一个元素。
i.remove();
if (seletK.isAcceptable()) {
//测试此键的通道是否已准备好接受新的套接字连接
System.out.println("测试此键的通道是否已准备好接受新的套接字连接");
Socket socket = ((ServerSocketChannel) seletK.channel()).accept().socket(); // 获取与此通道关联的套接字。
sc = socket.getChannel(); //返回与此数据报套接字关联的唯一 SocketChannel 对象
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
if (seletK.isReadable()) {
//测试此键的通道是否已准备好进行读取。
System.out.println("read a message from client!");
}
}
}
}
}
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
控制台信息
invoke startServer---------------------
nKeys=1
测试此键的通道是否已准备好接受新的套接字连接
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
nKeys=1
read a message from client!
。。。。。。
死循环下去了
while (stop) {
synchronized (this) {
nKeys = selector.select(); //选择一组键,其相应的通道已为 I/O 操作准备就绪。返回已更新其准备就绪操作集的键的数目、
System.out.println("nKeys=" + nKeys);
if (nKeys > 0) {
Set<SelectionKey> selectedKeys = selector.selectedKeys(); //返回此选择器的已选择键集。
Iterator i = selectedKeys.iterator(); //返回在此 set 中的元素上进行迭代的迭代器
while (i.hasNext()) {
//如果仍有元素可以迭代,则返回 true
seletK = (SelectionKey) i.next(); //返回迭代的下一个元素。
i.remove();
if (seletK.isAcceptable()) {
//测试此键的通道是否已准备好接受新的套接字连接
System.out.println("测试此键的通道是否已准备好接受新的套接字连接");
Socket socket = ((ServerSocketChannel) seletK.channel()).accept().socket(); // 获取与此通道关联的套接字。
sc = socket.getChannel(); //返回与此数据报套接字关联的唯一 SocketChannel 对象
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
if (seletK.isReadable()) {
//测试此键的通道是否已准备好进行读取。
System.out.println("read a message from client!");
}
}
}
}
}