package xx.xx.xx;
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.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import org.apache.log4j.Logger;
import cn.istorm.gm.websocket.WebSocket;
public class Server {
private static final Logger logger = Logger.getLogger(Server.class);
//监听端口
private static final int PORT = 18085;
//读缓冲区大小
private static final int READBUFFERSIZE = 2048;
//写缓冲区大小
private static final int WRITERBUFFERSIZE = 15;
//读缓冲区
private static ByteBuffer readbuffer = null;
//写缓冲区
private static ByteBuffer writerbuffer = null;
//ip白名单
private static Set<String> ip_set = null;
//选择器
private Selector selector;
static {
//读缓冲区实例
readbuffer = ByteBuffer.allocate(READBUFFERSIZE);
//写缓冲区实例
writerbuffer = ByteBuffer.allocate(WRITERBUFFERSIZE);
//ip白名单实例
ip_set = new HashSet<String>();
//读取配置文件IP白名单
String ips = PropertiesUtils.getProperty("socket.server.ip");
if (ips != null && ips != "") {
ips = ips.trim();
String[] ipArray = ips.split(",");
for (String ip : ipArray) {
ip = ip.trim();
if (ip == "") {
continue;
}
ip_set.add(ip);
}
}
}
public Server(int port) throws IOException {
//开启一个socket服务
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//设置异步
serverSocketChannel.configureBlocking(false);
//绑定端口
serverSocketChannel.socket().bind(new InetSocketAddress(port));
//开启一个选择器
this.selector = Selector.open();
//注册监听事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
logger.info("socket服务端开启服务成功,监听端口:" + port);
}
public Server() throws IOException {
this(PORT);
}
//用一个线程循环监听
public void listen() {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
//监听,这里会阻塞
int select = selector.select();
if (select <= 0) {
continue;
}
} catch (IOException e) {
logger.error("socket服务端监听异常", e);
continue;
}
//获取key集合
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey selectionKey = it.next();
//删除key
it.remove();
//处理事件
handle(selectionKey);
}
}
}
}).start();
logger.info("socket服务端开启监听服务成功");
}
//处理事件
private void handle(SelectionKey selectionKey) {
switch (selectionKey.readyOps()) {
case SelectionKey.OP_CONNECT:
break;
case SelectionKey.OP_ACCEPT:
this.accept(selectionKey);
break;
case SelectionKey.OP_READ:
this.read(selectionKey);
break;
case SelectionKey.OP_WRITE:
this.writer(selectionKey);
break;
default:
break;
}
}
//接收连接事件
private void accept(SelectionKey selectionKey) {
SocketChannel client = null;
try {
client = ((ServerSocketChannel) selectionKey.channel()).accept();
String remoteAddress = client.getRemoteAddress().toString().replaceAll("/", "");
String remoteAddress1 = remoteAddress.substring(0, remoteAddress.indexOf(".", remoteAddress.indexOf(".") + 1));
String remoteAddress2 = remoteAddress.substring(0, remoteAddress.lastIndexOf(":"));
if (!ip_set.contains(remoteAddress1) && !ip_set.contains(remoteAddress2) && !ip_set.contains(remoteAddress)) {
throw new RuntimeException("socket连接被强制关闭,原因:访问IP不在白名单内,来源地址:" + remoteAddress);
}
client.configureBlocking(false);
client.register(this.selector, SelectionKey.OP_READ);
logger.info("socket连接成功,来源地址:" + client.getRemoteAddress());
} catch (Exception e) {
logger.error("socket连接异常", e);
try {if (client != null) {client.socket().close();client.close();}} catch (IOException e1) {logger.error("关闭socket异常", e1);}
}
}
//读取消息事件
private void read(SelectionKey selectionKey) {
SocketChannel client = null;
try {
client = (SocketChannel) selectionKey.channel();
readbuffer.clear();
int count = client.read(readbuffer);
if (count < 0) {
throw new RuntimeException("socket读取到已关闭的连接");
}
readbuffer.flip();
System.out.println(new String(readbuffer.array(), 0, count));
client.register(this.selector, SelectionKey.OP_WRITE);
logger.info("socket读取消息成功,共:" + count + "个字节,来源地址:" + client.getRemoteAddress());
} catch (Exception e) {
logger.error("socket读取消息异常", e);
try {if (client != null) {client.socket().close();client.close();}} catch (IOException e1) {logger.error("关闭socket异常", e1);}
}
}
//写出消息事件
private void writer(SelectionKey selectionKey) {
SocketChannel client = null;
try {
client = (SocketChannel) selectionKey.channel();
writerbuffer.clear();
writerbuffer.put("success".getBytes());
writerbuffer.flip();
client.write(writerbuffer);
client.register(this.selector, SelectionKey.OP_READ);
logger.info("socket写出消息成功");
} catch (Exception e) {
logger.error("socket写出消息异常", e);
try {if (client != null) {client.socket().close();client.close();}} catch (IOException e1) {logger.error("关闭socket异常", e1);}
}
}
public void close() {
if (this.selector != null) {
try {
this.selector.close();
} catch (Exception e) {
logger.error("关闭selector异常", e);
}
}
}
}