package com.itproject.project.job.service.impl;
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.Iterator;
public class Myserver {
private int size = 1024;
private ServerSocketChannel serverSocketChannel;
private ByteBuffer byteBuffer ;
private Selector selector;
private int remoteClientNum = 0;
public Myserver(int port){
try {
initChannel(port);
}catch (IOException e){
e.printStackTrace();
System.exit(-1);
}
}
// Channel 得初始化
public void initChannel(int port) throws IOException {
//打开Channel
serverSocketChannel = ServerSocketChannel.open();
//设置为非阻塞模式
serverSocketChannel.configureBlocking(false);
//绑定端口
serverSocketChannel.bind(new InetSocketAddress(port));
System.out.println("listener on port: "+port);
//创建选择器
selector = Selector.open();
//想选择器注册通道
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
//分配缓冲区大小
byteBuffer = ByteBuffer.allocate(size);
}
//监听器,用于监听Channel 上得数据变化
private void listener() throws Exception {
while (true){
//返回多少int 类型得数值表示有多少个Channel处于就绪状态
int n = selector.select();
if(n==0){
continue;
}
//一个selector对于多个SelectionKey, 一个SelectionKey 对于一个Channel
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()){
SelectionKey key = iterator.next();
//如果SelectionKey 处于连接就绪状态,则开始接受客户端得连接
if (key.isAcceptable()){
//获得channel
ServerSocketChannel server = (ServerSocketChannel) key.channel();
//channel 接受链接
SocketChannel channel = server.accept();
//channel 注册
registerChannel(selector,channel,SelectionKey.OP_READ);
//远程客户端的连接数统计
remoteClientNum ++;
System.out.println("online client num = "+remoteClientNum);
write(channel,"hello client ".getBytes());
}
//如果通道已经处在读就绪状态,则读取通道的数据
if (key.isReadable()){
read(key);
}
iterator.remove();
}
}
}
private void read(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
int count;
byteBuffer.clear();
//从通道读取数据到缓冲区
while ((count =socketChannel.read(byteBuffer))>0){
//byteBuffer 从写模式变为读模式
byteBuffer.flip();
while (byteBuffer.hasRemaining()){
System.out.println((char)byteBuffer.get());
};
byteBuffer.clear();
}
if(count <0){
socketChannel.close();
}
}
private void write(SocketChannel channel, byte[] writeDate) throws IOException {
byteBuffer.clear();
byteBuffer.put(writeDate);
byteBuffer.flip();
//将缓冲区的数据写入通道
channel.write(byteBuffer);
}
private void registerChannel(Selector selector, SocketChannel channel, int opRead) throws IOException {
if (channel == null){
return;
}
channel.configureBlocking(false);
channel.register(selector,opRead);
}
public static void main(String[] args) {
try {
Myserver myserver = new Myserver(9999);
myserver.listener();
}catch (Exception e){
e.printStackTrace();
}
}
}
package com.itproject.project.job.service.impl;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class MyClient {
private int size = 1024;
private SocketChannel socketChannel;
private ByteBuffer byteBuffer ;
public void connectServer() throws IOException {
//打开通道
socketChannel = socketChannel.open();
//设置连接地址和端口
socketChannel.connect(new InetSocketAddress("127.0.0.1",9999));
//设置为非阻塞模式
socketChannel.configureBlocking(false);
byteBuffer = ByteBuffer.allocate(size);
receive();
}
private void receive() throws IOException {
while (true){
byteBuffer.clear();
int count;
//如果没有数据可读,则read方法一直阻塞,置到读取新数据
while ((count = socketChannel.read(byteBuffer))>0){
byteBuffer.flip();
while (byteBuffer.hasRemaining()){
System.out.println((char) byteBuffer.get());
}
send2Server("say hi".getBytes());
}
}
}
private void send2Server(byte[] bytes) throws IOException {
byteBuffer.clear();
byteBuffer.put(bytes);
byteBuffer.flip();
socketChannel.write(byteBuffer);
}
public static void main(String[] args) throws IOException {
new MyClient().connectServer();
}
}
以上代码可以直接复制拿来测试即可!!谢谢各位!