一、主要目的
设计关系型数据库服务器的内部执行逻辑。
二、具体逻辑
(一)服务器主进程的逻辑
// 初始化
init();
// 开始监听关闭信号线程
openCloseSignalThread();
// 循环处理,如果运行为真
while(isRun.get()){
// 阻塞获取客户端连接
Socket sock = server.accept();
// 开启子线程处理
Thread temp = new Thread(new Task(sock));
temp.start();
}
// 销毁资源
destroy();
(二)监听关闭信号线程的逻辑
收到客户端的关闭信号,就立刻关闭主线程。
while(true){
// 收听一个TCP客户端连接
Socket socket = server.accept();
// 设置读取超时为2000毫秒
socket.setSoTimeout(2000);
try{
// 获得输入流
InputStream input = socket.getInputStream();
// 读取关闭数据包
byte[] data = getClosePacket(input);
// 验证权限,判断为关闭信号
if(hasPermision(data) && isClose(data)) {
// 停止主进程,关闭主进程的服务端套接字
isRun.set(false);
main.close();
socket.close();
break;
}
} catch(IOException e) {
// 关闭客户端套接字
socket.close();
} finally {
如果不为空,并且没有关闭
if(socket != null && !socket.isClosed()){
socket.close();
}
}
}
// 关闭自己的套接字
server.close();
(三)处理任务线程的逻辑
public class Task implements Runnable{
private Socket socket;
public Task(Socket socket){
this.socket = socket;
}
@Override
public void run(){
InputStream input = socket.getInputStream();
OutputStream output = socket.getOutputStream();
// 发给客户端握手包
sendHandshake(output);
// 读取客户端发来的登录包
LoginInfo info = readLogin(input);
// 判断是否登录成功
if(login(info)){
// 回复登录成功
reply(output, 100, "login ok");
// 进入循环
while(true){
// 读取SQL语句
String sql = readSQL(input);
// 如果是退出
if(sql.equals("exit"){
// 跳出循环
break;
} else {
// 判断是否有权限执行
if(hasPermission(sql, info)){
// 执行语句,返回结果
Result result = execute(sql);
// 回复执行结果
replyResult(output, result);
} else {
// 回复无权限
reply(output, 400, "no permission");
}
}
}
} else {
// 回复登录失败,用户名或者密码不存在
reply(output, 300, "login fail, user or password incorrect.");
}
// 关闭流
input.close();
output.close();
socket.close();
}
}
三、主要难点
1、握手包的格式
2、登录包的格式
3、命令包的格式
4、结果包的格式
5、登录验证,权限验证的逻辑
6、执行SQL语句的方法逻辑
评论前必须登录!
注册