此类由org.h2.tools.Server触发 此类中的方法调用顺序是: init => start => listen => isRunning listen和isRunning几乎是同时执行,isRunning用于测试是否在本地连得上TcpServer //每建立一个新的Session对象时,把它保存到内存数据库management_db_9092的SESSIONS表 stat.execute("CREATE TABLE IF NOT EXISTS SESSIONS(ID INT PRIMARY KEY, URL VARCHAR, USER VARCHAR, CONNECTED TIMESTAMP)"); managementDbAdd = conn.prepareStatement("INSERT INTO SESSIONS VALUES(?, ?, ?, NOW())"); managementDbRemove = conn.prepareStatement("DELETE FROM SESSIONS WHERE ID=?"); server端有一个listen线程, org.h2.server.TcpServer.listen() 一直在监听客户端连接, 一但收到客户端连接请求就开一个新的线程处理它(并未使用线程池、每连接每线程) 协议如下: client先发数据:(见: org.h2.engine.SessionRemote.initTransfer(ConnectionInfo, String, String)) int minClientVersion int maxClientVersion String db String URL String userName byte[] userPasswordHash byte[] filePasswordHash int keys length keys length个 { String key String value } 还有两种特殊情况: 在org.h2.server.TcpServerThread.run()中特殊情理,对应if (db == null && originalURL == null)这个语句 SessionRemote.SESSION_CANCEL_STATEMENT ==================================== int minClientVersion int maxClientVersion String null String null String sessionId int SessionRemote.SESSION_CANCEL_STATEMENT(13) int statement id ==================================== 见: org.h2.engine.SessionRemote.cancelStatement(int) SessionRemote.SESSION_CHECK_KEY ==================================== int minClientVersion int maxClientVersion String null String null String sessionId int SessionRemote.SESSION_CHECK_KEY(14) ==================================== 见: org.h2.store.FileLock.checkServer() server响应: STATUS_OK: ==================================== int STATUS_OK(1) int clientVersion ==================================== STATUS_ERROR: ==================================== int STATUS_ERROR(0) String SQLState value String message String sql int errorCode String trace ==================================== 见org.h2.server.TcpServerThread.sendError(Throwable) 第一个握手包处理完之后,就可以一直使用长连接来发命令了: 命令协议包: int operation 每个命令都有自己的格式 具体见: org.h2.server.TcpServerThread.process() client端发的第一个命令一般是SessionRemote.SESSION_PREPARE_READ_PARAMS/SESSION_PREPARE 具体见: org.h2.command.CommandRemote.prepare(SessionRemote, boolean) 流程: org.h2.server.TcpServer.listen() => org.h2.server.TcpServerThread.run() => org.h2.engine.Engine.createSession(ConnectionInfo) => org.h2.server.TcpServerThread.process()