62,614
社区成员
发帖
与我相关
我的任务
分享
public class DataServer {
public static ArrayList<SelectorLoop> connectionBellList = new ArrayList<>();
public boolean isReadBellRunning = false;
public long requestCount = 0;
public static ServerSocketChannel ssc;
public static ExecutorService executorService = Executors
.newFixedThreadPool(30);
public static void main(String[] args) throws IOException {
new DataServer().startServer();
}
// 启动服务器
public void startServer() throws IOException {
// 准备好闹钟.当有链接进来的时候响.
for ( int i = 0; i < 5;i++ ){
SelectorLoop selectorLoop = new SelectorLoop();
connectionBellList.add(selectorLoop);
}
// 开启一个server channel来监听
ssc = ServerSocketChannel.open();
// 开启非阻塞模式
ssc.configureBlocking(false);
ServerSocket socket = ssc.socket();
socket.bind(new InetSocketAddress("localhost", 7878));
// 给闹钟规定好要监听报告的事件,这个闹钟只监听新连接事件.
for ( int i = 0; i < connectionBellList.size();i++ ){
ssc.register(connectionBellList.get(i).getSelector(), SelectionKey.OP_ACCEPT);
new Thread(connectionBellList.get(i)).start();
}
}
public static class SendThread implements Runnable {
private SocketChannel sc;
private ByteBuffer temp;
private String msg;
private long count;
/**
* @param sc
* @param msg
*/
public SendThread(SocketChannel sc, String msg) {
this.sc = sc;
this.temp = ByteBuffer.allocate(1024);
this.msg = msg;
}
@Override
public void run() {
try {
sc.write(ByteBuffer.wrap(msg.getBytes(Charset.forName("UTF-8"))));
// 清空buffer
temp.clear();
} catch (IOException e) {
System.out.println("channel is null");
} catch (Exception e) {
System.out.println("通道异常");
}
}
}
// Selector轮询线程类
public static class SelectorLoop implements Runnable {
private Selector selector;
private ByteBuffer temp = ByteBuffer.allocate(1024);
private String msg = "this is a message...";
public static long requsts = 0;
public SelectorLoop() throws IOException {
this.selector = Selector.open();
}
public Selector getSelector() {
return this.selector;
}
public static synchronized long addCount() {
return ++requsts;
}
@Override
public void run() {
System.out.println("Server start 。。。。 ");
while (true) {
Iterator<SelectionKey> it;
try {
// 阻塞,只有当至少一个注册的事件发生的时候才会继续.
synchronized (ssc) {
this.selector.select();
}
// 获取事件
Set<SelectionKey> selectKeys = this.selector.selectedKeys();
it = selectKeys.iterator();
System.out.println("connection : " + addCount());
while (it.hasNext()) {
SelectionKey key = it.next();
it.remove();
// 处理事件. 可以用多线程来处理.
if (key.isAcceptable()) {
// 这是一个connection accept事件,
// 并且这个事件是注册在serversocketchannel上的.
ServerSocketChannel ssc = (ServerSocketChannel) key
.channel();
// 接受一个连接.
SocketChannel sc = ssc.accept();
// 在线程池中执行数据传输
executorService.execute(new SendThread(sc, msg));
this.selector.wakeup();
// new Thread(new SendThread(sc,
// msg,++requestCount)).start();
}
}
} catch (IOException e) {
System.out.println("存在客户端强制断开连接断开连接!");
}
}
}
}
}
public class DataClient{
public static void main(String[] args) throws IOException {
// 线程总数 Threadsum * 111
int threadSum = 5;
for ( int i = 0; i < threadSum;i++ ){
new Thread(new ClientThread(2)).start();
}
}
public static class ClientThread implements Runnable{
public static long timeoutCount = 0;
private static int idleCounter = 0;
private Selector selector;
private SocketChannel socketChannel;
private ByteBuffer temp = ByteBuffer.allocate(1024);
private int deep;
public ClientThread(int deep) {
this.deep = deep;
// 同样的,注册闹钟.
try {
this.selector = Selector.open();
// 连接远程server
socketChannel = SocketChannel.open();
// 如果快速的建立了连接,返回true.如果没有建立,则返回false,并在连接后出发Connect事件.
Boolean isConnected = socketChannel.connect(new InetSocketAddress(
"localhost", 7878));
socketChannel.configureBlocking(false);
SelectionKey key = socketChannel.register(selector,
SelectionKey.OP_READ);
if (!isConnected) {
// 如果连接还在尝试中,则注册connect事件的监听. connect成功以后会出发connect事件.
key.interestOps(SelectionKey.OP_CONNECT);
}
} catch (IOException e) {
System.out.println(Thread.currentThread().getName()+" 连接异常 : #"+ (++timeoutCount));
}
}
@Override
public void run() {
// 模拟并发
if (deep > 0) {
for ( int i = 0; i < 10;i++ ){
new Thread(new ClientThread(deep-1)).start();
}
}
while (true) {
try {
// 阻塞,等待事件发生,或者1秒超时. num为发生事件的数量.
int num = this.selector.select(5000);
if (num == 0) {
idleCounter++;
if (idleCounter > 2) {
// System.out.println("连接超时,线程 : "+Thread.currentThread().getName()+" 退出 #"+(++timeoutCount));
return;
}
continue;
}
Set<SelectionKey> keys = this.selector.selectedKeys();
Iterator<SelectionKey> it = keys.iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
it.remove();
if (key.isConnectable()) {
// socket connected
SocketChannel sc = (SocketChannel) key.channel();
if (sc.isConnectionPending()) {
sc.finishConnect();
}
}
// 接收到消息
if (key.isReadable()) {
// msg received.
SocketChannel sc = (SocketChannel) key.channel();
this.temp = ByteBuffer.allocate(1024);
int count = sc.read(temp);
if (count < 0) {
sc.close();
continue;
}
// 切换buffer到读状态,内部指针归位.
temp.flip();
String msg = Charset.forName("UTF-8").decode(temp)
.toString();
System.out.println(Thread.currentThread().getName()+" Client received [" + msg
+ "] ");
return ;
}
}
} catch (IOException e) {
System.out.println("远程主机已关闭,程序退出!");
return;
}
}
}
}
}