package ALBasicServer.ALSocket;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
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;
import java.util.Set;
import ALBasicServer.ALVerifyObj.ALVerifyObjMgr;
import ALBasicServer.ALVerifyObj._IALVerifyFun;
import ALServerLog.ALServerLog;
/***********************
* 服务器监听端口的处理函数类,部分操作由于需要访问内部函数,因此独立
*
* @author alzq.z
* @email zhuangfan@vip.163.com
* @time Feb 19, 2013 4:39:40 PM
*/
public class ALServerSocketListenFunction
{
/** 分配Socket连接的ID标志 */
private static long g_socketSerialize = 1;
/**********************
* 开启服务器监听端口,并对所有返回数据做处理
*
* @author alzq.z
* @time Feb 19, 2013 4:34:07 PM
*/
public static void startServer(int _port, int _recBuffLen, _IALVerifyFun _verifyObj)
{
InetSocketAddress socketAddress = new InetSocketAddress(_port);
Selector selector = null;
//注册验证处理对象
int verifyObjIdx = ALVerifyObjMgr.getInstance().regVerifyObj(_verifyObj);
//创建接收BUF
ByteBuffer recBuffer = ByteBuffer.allocate(_recBuffLen * 2);
try {
//创建事件响应对象
selector = Selector.open();
//创建服务器channel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
//绑定socket
ServerSocket serverSocket = serverSocketChannel.socket();
serverSocket.bind(socketAddress);
//注册处理事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
}
catch (IOException e)
{
//开启端口失败
ALServerLog.Fatal("Open server port error!!");
e.printStackTrace();
return ;
}
ALServerLog.Info("Server Start socket...");
//开启循环处理Socket事件
while(true)
{
try
{
selector.select();
} catch (Exception e) {
ALServerLog.Fatal("Server port select event error!!");
e.printStackTrace();
}
//循环获取到的事件
Set<SelectionKey> readyKeySet = selector.selectedKeys();
Iterator<SelectionKey> iter = readyKeySet.iterator();
while(iter.hasNext())
{
SelectionKey key = (SelectionKey)iter.next();
//移除已经取出的事件
iter.remove();
try
{
if(key.isAcceptable())
{
//收到一个接受连接的操作
ServerSocketChannel serverSocketChannel = (ServerSocketChannel)key.channel();
try
{
SocketChannel client = serverSocketChannel.accept();
ALServerLog.Info("Accept a client connection ");
client.configureBlocking(false);
ALBasicServerSocket newSocket = new ALBasicServerSocket(_getSocketID(), verifyObjIdx, client, _recBuffLen);
//将对象及其ID注册
ALServerSocketMgr.getInstance().regSocket(newSocket);
//注册读取事件,读取操作由server socket channel处理,写入操作可直接对socket channel进行操作
client.register(selector, SelectionKey.OP_READ);
}
catch (Exception e)
{
ALServerLog.Fatal("Server port accept error!!");
e.printStackTrace();
}
}
else if(key.isReadable())
{
//收到数据
SocketChannel socketChannel = (SocketChannel)key.channel();
//读取数据
try
{
recBuffer.clear();
//此时进行读取,当读取的包大小超过存储区域则可能导致数据读取不全
int recLen = socketChannel.read(recBuffer);
//设置限制,并将读取位置归0
recBuffer.flip();
if(recLen <= 0)
{
if(recLen < 0)
{
//尝试在对应Socket存储结构体中删除对应Socket
ALServerSocketMgr.getInstance().unregSocket(socketChannel);
}
continue;
}
//尝试在已注册对象中查询对应Socket
ALBasicServerSocket socket = ALServerSocketMgr.getInstance().getSocket(socketChannel);
if(null == socket)
continue;
//处理消息读取
socket._socketReceivingMessage(recBuffer);
}
catch (IOException e)
{
//尝试在对应Socket存储结构体中删除对应Socket
ALServerSocketMgr.getInstance().unregSocket(socketChannel);
}
}
}
catch (Exception e) {
}
}
}
}
/**************
* 获取新的SocketID
* @return
*/
protected static synchronized long _getSocketID()
{
return g_socketSerialize++;
}
}