package mx; import java.io.*; public class mxmain { public String version = "0.001"; public mxserver ls; public static String welcome = "MX Server"; public boolean start = false; public static int serverID; public static String ip = ""; public static int port = 9090; public static String mysql_ip = "127.0.0.1"; public int mysql_port = 3306; public String mysql_user = "root"; public String mysql_pass = ""; public String mysql_db = "demo"; public static String conf_filename = "/home/mx/server.conf"; /** Creates a new instance of mxmain */ public mxmain() { try { String filename = conf_filename; //System.out.println(filename); FileReader fr = new FileReader(filename); BufferedReader br = new BufferedReader(fr); while (true) { String buf = br.readLine(); if (buf == null) { break; } String[] tmp = buf.split("="); if (buf.startsWith("ip=")) { ip = tmp[1]; } else if (buf.startsWith("port=")) { port = Integer.parseInt(tmp[1]); } else if (buf.startsWith("mysql_ip=")) { mysql_ip = tmp[1]; } else if (buf.startsWith("mysql_port=")) { mysql_port = Integer.parseInt(tmp[1]); } else if (buf.startsWith("mysql_user=")) { mysql_user = tmp[1]; } else if (buf.startsWith("mysql_pass=")) { mysql_pass = tmp[1]; } else if (buf.startsWith("mysql_db=")) { mysql_db = tmp[1]; } else if (buf.startsWith("serverID=")) { serverID = Integer.parseInt(tmp[1]); } else if (buf.startsWith("maxthread=")) { mxserver.MAX_THREAD = Integer.parseInt(tmp[1]); } } fr.close(); } catch (Exception e) { } } public int start() { start = true; ls = new mxserver(this); if (ls.error != 0) { ls.start = false; return ls.error; } ls.start(); return 0; } public void stop() { start = false; ls.mxstop(); SQL.Bye(); } } package mx; import java.io.*; import java.util.*; import java.net.*; import java.nio.channels.*; import java.sql.ResultSet; import java.text.*; public class mxserver extends Thread { public boolean start = false; public static int MAX_THREAD = 10; public static mxthread[] threads; public boolean done = false; public int error = 0; public mxmain lm; public static Time timer = null; public static Log log = null; public String starttime = ""; public ServerSocketChannel ssc; private static FileWriter ips; public mxserver(mxmain lm) { this.lm = lm; error = 0; start = true; threads = new mxthread[MAX_THREAD]; for (int i = 0; i < MAX_THREAD; i++) { threads[i] = null; } for (int i = 0; i < MAX_THREAD; i++) { threads[i] = new mxthread(); threads[i].setName("RAY-Player-" + i); threads[i].enable = false; threads[i].start(); } init(); // SQL.init(mxmain.mysql_ip, lm.mysql_port, lm.mysql_user, lm.mysql_pass, lm.mysql_db); // InitGames(); } private void init() { File dir = new File("/home/mx/logs"); dir.mkdirs(); File dir2 = new File("/home/mx/debug"); dir2.mkdirs(); try { Enumeration e = NetworkInterface.getNetworkInterfaces(); while (e.hasMoreElements()) { NetworkInterface netface = (NetworkInterface) e.nextElement(); Enumeration e2 = netface.getInetAddresses(); while (e2.hasMoreElements()) { InetAddress ip = (InetAddress) e2.nextElement(); if (ip.getHostAddress().equals("127.0.0.1")) { continue; } if (ip.getHostAddress().equals("210.51.38.97")) { continue; } String temp[] = ip.getHostAddress().split("//."); if (temp.length != 4) { continue; } if (mxmain.ip.length() == 0) { mxmain.ip = new String(ip.getHostAddress()); } break; } } } catch (Exception e) { } } private void InitGames() { Monitor.init(); Monitor.freeMemo = "init mem:max=" + Monitor.runtime.maxMemory() + ",free=" + Monitor.runtime.freeMemory() + Const.crlf; //启动定时器 timer = new Time(1000); timer.setName("RAY-Time-Main"); timer.start(); Monitor.freeMemo += "Time=" + Monitor.runtime.freeMemory() + Const.crlf; sqlinit(); /* Log.init(); log = new Log(); log.start(); * */ } private static void sqlinit() { ResultSet rs; rs = SQL.Select("select * from think_access;"); if (rs == null) { return; } try { rs.last(); if (rs.getRow() != 0) { rs.beforeFirst(); while (rs.next()) { int id = rs.getInt("node_id"); System.out.println("node_id: " + id); } rs = null; } } catch (Exception e) { } } @Override public void run() { java.util.Date d = new java.util.Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); starttime = dateFormat.format(d); SystemLog("Server started."); mxthread th = null; Selector acceptSelector = null; try { acceptSelector = Selector.open(); ssc = ServerSocketChannel.open(); ssc.configureBlocking(false); InetSocketAddress isa = new InetSocketAddress(InetAddress.getByName(mxmain.ip), mxmain.port); ssc.socket().bind(isa); ssc.register(acceptSelector, SelectionKey.OP_ACCEPT); } catch (IOException e) { error = 3; System.out.println("mxserver: " + e.getMessage()); } System.out.println("Welcome to the server!"); System.out.println(new java.util.Date()); System.out.println("The server is ready!"); System.out.println("IP/Port: " + mxmain.ip + ":" + mxmain.port); int keysAdded = 0; while (!done) { try { keysAdded = acceptSelector.select(1000); } catch (Exception e) { } //System.out.println("keys="+keysAdded); if (keysAdded <= 0) { continue; } Set readyKeys = acceptSelector.selectedKeys(); Iterator i = readyKeys.iterator(); while (i.hasNext()) { SelectionKey sk = (SelectionKey) i.next(); i.remove(); if (!sk.isAcceptable()) { continue; } ServerSocketChannel nextReady = (ServerSocketChannel) sk.channel(); if (nextReady == null) { continue; } Socket request2 = null; SocketChannel sc = null; try { sc = nextReady.accept(); } catch (Exception e) { continue; } if (sc == null) { continue; } try { request2 = sc.socket(); } catch (Exception e) { continue; } try { request2.setTcpNoDelay(true); ips = new FileWriter("/home/mx/ips", true); ips.append("time=" + System.currentTimeMillis() + ",ip=" + request2.getRemoteSocketAddress() + "/r/n"); ips.close(); } catch (Exception e) { } int j; for (j = 0; j < MAX_THREAD; j++) { if ((threads[j] == null) || (threads[j].enable == false)) { break; } } if (j == MAX_THREAD) { //System.out.println("HTTP/1.0 OK 200/n/ntoo many connections."); try { request2.close(); } catch (Exception e) { } continue; } th = threads[j]; if (th == null) { th = new mxthread(); threads[j] = th; try { th.clientRequest = request2; th.ip = request2.getInetAddress().getHostAddress(); th.input = new DataInputStream(request2.getInputStream()); th.output = new DataOutputStream(request2.getOutputStream()); } catch (Exception e) { continue; } th.enable = true; th.start(); } else { try { th.clear(); th.clientRequest = request2; th.ip = request2.getInetAddress().getHostAddress(); th.input = new DataInputStream(request2.getInputStream()); th.output = new DataOutputStream(request2.getOutputStream()); } catch (Exception e) { } synchronized (th) { th.enable = true; th.notify(); } } } } try { ssc.socket().close(); } catch (Exception e) { } } public void mxstop() { SystemLog("Server stopped."); Time.run = false; for (int i = 0; i < MAX_THREAD; i++) { if (threads[i] == null) { continue; } mxthread th = (mxthread) threads[i]; try { } catch (Exception e) { } } //log.over(); //SQL.flush(); done = true; } public boolean SystemLog(String str) { java.util.Date d = new java.util.Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); String today = dateFormat.format(d); SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String now = dateFormat2.format(d); String filename = "/home/mx/logs/system.log"; try { FileWriter fw = new FileWriter(filename, true); fw.append(now + " " + str + "/n"); fw.close(); } catch (Exception e) { return false; } return true; } } package mx; import java.io.*; import java.net.*; import java.util.Vector; public class mxthread extends Thread { public Socket clientRequest; private DataInputStream in; public DataInputStream input; public DataOutputStream output; /** 是否运行 */ public boolean enable = true; /** 接收协议时间 */ public int now = 0; /** 处理完协议时间 */ public int end = 0; /** 收到数据字节数 */ public int dataInNum; /** 发送数据字节数 */ public int dataOutNum; /** 收到协议数 */ public int cmdInNum; /** 发送协议数 */ public int cmdOutNum; /** 资源下载字节数 */ public int resDownload; /** 资源下载请求数 */ public int resReqNum; /** 空包请求数 */ public int emptyNum; /** 发送次数 */ public int flushNum; /** 线程读操作超时时间 */ public int read_out = 300; /** 发送协议间隔 */ public int flush_out = 300; /** 最后一次发送协议时间 */ public long lastFlush; /** 收到的最后一个协议 */ public short lastCmd; /** IP地址 */ public String ip; /** 协议头前置 */ public short pref; /** 收到协议 */ public Request request = new Request(); /** 发送协议缓存 */ public Vector respBuf = new Vector(); public mxthread() { enable = false; } public void run() { while (true) { synchronized (this) { while (enable == false) { try { this.wait(); } catch (Exception e) { } } } try { pref = input.readShort(); clientRequest.setSoTimeout(this.read_out); } catch (Exception e) { } DoData(); } } public void DoData() { while (true) { try { if (input == null || output == null) { break; } if (!request.readFromInputStream(input)) { break; } if (request.isComplete()) { in = request.getInputStream(); this.cmdInNum++; this.dataInNum += in.available() + 4; if (in.available() == 0) { output.writeInt(0); output.flush(); this.flushNum++; this.emptyNum++; this.cmdOutNum++; this.dataOutNum += 4; } else { short cmd = in.readShort(); PreCommand(cmd); this.lastCmd = cmd; } } } catch (SocketTimeoutException e) { } catch (Exception e) { // e.printStackTrace(); break; } try { if (respBuf.size() == 0) { continue; } if (System.currentTimeMillis() - this.lastFlush < this.flush_out) { continue; } flush(); } catch (Exception e) { break; } } clear(); } public void clear() { try { if (input != null) { input.close(); } if (output != null) { output.close(); } if (clientRequest != null) { clientRequest.close(); } request.clear(); respBuf.clear(); } catch (Exception e) { e.printStackTrace(); } enable = false; } public void send(Response rsp) { byte[] b = new byte[rsp.size]; System.arraycopy(rsp.data, 0, b, 0, rsp.size); respBuf.add(b); this.cmdOutNum++; this.dataOutNum += 4 + rsp.size; } private void flush() { try { byte[][] data; synchronized (respBuf) { data = new byte[respBuf.size()][]; respBuf.copyInto(data); respBuf.clear(); } for (int i = 0; i < data.length; i++) { int len = data[i].length; if (len < 1) { continue; } output.writeInt(len); output.write(data[i]); } output.flush(); this.flushNum++; lastFlush = System.currentTimeMillis(); } catch (Exception e) { } } private void PreCommand(short cmd) { try { switch (cmd) { case 1: //userID = in.readInt(); //pass = in.readUTF(); //mobileID = in.readLong(); //line = in.readByte(); Login(); break; case 11: Response rsp = Response.newResponse(11, this); rsp.write(Const.OK); rsp.send(false); break; case 102: break; default: break; } } catch (Exception e) { e.printStackTrace(); String str = "time=" + Time.time + ",cmd=" + cmd; System.out.print(str); } } private void Login() { try { String str = "hello"; Response rsp = Response.newResponse(1, this); rsp.write(121); rsp.write(str); rsp.send(true); } catch (Exception e) { } } private boolean auth(Response rsp) { /* String str; try { HttpConnect connect = new HttpConnect(); str=connect.conn("10 "+userID+" "+pass+" "+ip+" "+mxmain.serverID); String[] tmp=str.split(" "); byte resType = Byte.parseByte(tmp[0]); if(resType == 0) { yuan = Integer.parseInt(tmp[1]); } else { rsp.write(Const.ERR); rsp.write(tmp[1]); rsp.send(true); return false; } } catch (Exception e) { e.printStackTrace(); } * */ return true; } } /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package mx; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; public class Request { private byte[] buf = new byte[128];// 默认大小 private int size; private int len; public void clear() { size = 0; } boolean readFromInputStream(InputStream in) throws IOException { int ch; while (true) { ch = in.read(); if (ch < 0) { return false; } if (buf.length == size) {// 容量不足是扩容 byte[] newBuf = new byte[size * 2]; System.arraycopy(buf, 0, newBuf, 0, size); this.buf = newBuf; newBuf = null; } buf[size++] = (byte) ch; if (size == 4) { len = (buf[3] & 0xFF) | ((buf[2] & 0xFF) << 8) | ((buf[1] & 0xFF) << 16) | ((buf[0]) << 24); } if (size >= 4 && size == len + 4) { return true; } } } boolean isComplete() { return size >= 4 && size == len + 4; } DataInputStream getInputStream() { byte[] b = new byte[len]; System.arraycopy(buf, 4, b, 0, len); size = 0; return new DataInputStream(new ByteArrayInputStream(b)); } } package mx; import java.io.*; import java.util.ArrayList; /** * * @author Administrator */ public class Response { public mxthread th = null; short protocolID; /** 数据包 */ byte[] data; /** 有效长度 */ int size = 0; /** * 新建一个请求 * @param protocolID 协议号 * @return */ public static Response newResponse(int protocolID, mxthread th) { return new Response((short) protocolID, th); } public static Response newResponse(int protocolID) { return new Response((short) protocolID); } public static Response newResponse(short protocolID) { return new Response(protocolID); } Response(short protocolID) { this.protocolID = protocolID; data = new byte[128]; data[size++] = (byte) (protocolID >>> 8); data[size++] = (byte) (protocolID >>> 0); } Response(short protocolID, mxthread th) { this.protocolID = protocolID; this.th = th; data = new byte[128]; data[size++] = (byte) (protocolID >>> 8); data[size++] = (byte) (protocolID >>> 0); } public final byte[] getData(int begin) { byte[] res = new byte[size - begin]; System.arraycopy(data, begin, res, 0, res.length); return res; } public final void send(boolean asap) { if (th != null) { th.send(this); // if (asap) { // th.flush(); // } } } /** * 返回请求数据的长度(包括协议号) * @return */ public final int size() { return size; } public final Response write(byte b) { this.ensureCapacity(size + 1); data[size++] = b; return this; } public final Response write(short s) { this.ensureCapacity(size + 2); data[size++] = (byte) (s >>> 8); data[size++] = (byte) (s >>> 0); return this; } public final Response write(int i) { this.ensureCapacity(size + 4); data[size++] = (byte) (i >>> 24); data[size++] = (byte) (i >>> 16); data[size++] = (byte) (i >>> 8); data[size++] = (byte) (i >>> 0); return this; } public final Response write(long l) { this.ensureCapacity(size + 8); data[size++] = (byte) (l >>> 56); data[size++] = (byte) (l >>> 48); data[size++] = (byte) (l >>> 40); data[size++] = (byte) (l >>> 32); data[size++] = (byte) (l >>> 24); data[size++] = (byte) (l >>> 16); data[size++] = (byte) (l >>> 8); data[size++] = (byte) (l >>> 0); return this; } public final Response write(byte[] b) { this.ensureCapacity(size + b.length); System.arraycopy(b, 0, data, size, b.length); size += b.length; return this; } public final Response write(short[] s) { this.ensureCapacity(size + s.length * 2); for (int i = 0; i < s.length; i++) { data[size++] = (byte) (s[i] >>> 8); data[size++] = (byte) (s[i] >>> 0); } return this; } /** * 写入一个字节数组 * @see DataOutput#write(byte[], int, int) */ public final Response write(byte[] b, int off, int len) { this.ensureCapacity(size + len); System.arraycopy(b, off, data, size, len); size += len; return this; } /** * 写入一个UTF字符串 * @see DataOutput#writeUTF(String) */ public final Response write(String str) { int strlen = str.length(); int utflen = 0; int c, count = 0; /* use charAt instead of copying String to char array */ for (int i = 0; i < strlen; i++) { c = str.charAt(i); if ((c >= 0x0001) && (c <= 0x007F)) { utflen++; } else if (c > 0x07FF) { utflen += 3; } else { utflen += 2; } } if (utflen > 65535) { throw new RuntimeException("UTFDataFormatException: encoded string too long: " + utflen + " bytes"); } byte[] bytearr = new byte[utflen + 2]; bytearr[count++] = (byte) (utflen >>> 8); bytearr[count++] = (byte) (utflen >>> 0); int i = 0; for (i = 0; i < strlen; i++) { c = str.charAt(i); if (!((c >= 0x0001) && (c <= 0x007F))) { break; } bytearr[count++] = (byte) c; } for (; i < strlen; i++) { c = str.charAt(i); if ((c >= 0x0001) && (c <= 0x007F)) { bytearr[count++] = (byte) c; } else if (c > 0x07FF) { bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F)); bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F)); bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F)); } else { bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F)); bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F)); } } this.ensureCapacity(size + utflen + 2); System.arraycopy(bytearr, 0, data, size, utflen + 2); size += utflen + 2; return this; } private void ensureCapacity(int minCapacity) { if (minCapacity > data.length) { int newCapacity = data.length * 3 / 2; if (newCapacity < minCapacity) { newCapacity = minCapacity; } byte[] newData = new byte[newCapacity]; System.arraycopy(data, 0, newData, 0, size); data = null; data = newData; } } } package mx; import java.text.SimpleDateFormat; import java.util.Date; public class Time extends Thread { /** 刷新类型:数据SQL语句 */ public final static byte DB = 1; /** 清除线程时间 */ public static int clearThread = 0; /** 当前时间:长整型 */ public static long lNow; /** 当前时间:整型 */ public static int now; /** 当前yyyy-mm-dd类型时间 */ public static String date; /** 当前yyyy-mm-dd hh:mm:ss类型时间 */ public static String time; /** 当前分钟 */ public static byte minute; /** 当前秒 */ public static byte second; /** 当前dd日 */ public static byte day; /** 当前hh小时 */ public static byte hour; /** 结束标志 */ public static boolean run = true; /** 打印日志最小时间 */ public static int minLog = 0; /** 间隔等待时间 */ public int wait = 0; public Time(int wait) { this.wait = wait; } public void run() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); while(run) { try { time = sdf.format(new Date()); hour = Byte.parseByte(time.substring(11, 13)); minute = Byte.parseByte(time.substring(14, 16)); second = Byte.parseByte(time.substring(17, 19)); day = Byte.parseByte(time.substring(8,10)); date = time.substring(0, 10); lNow = System.currentTimeMillis(); now = (int) (lNow / 1000); thread(); sleep(wait); } catch (Exception e) { e.printStackTrace(); } } } private static void thread() { try { if(Time.now - clearThread <= 60) return; clearThread = Time.now; //HttpConnect connect = new HttpConnect(); //String res = connect.conn("20 " + mxmain.myServerID + " " + user_online); //connect = null; mxthread th; for(int i = 0; i < mxserver.MAX_THREAD; i++) { th = mxserver.threads[i]; if (th == null || th.enable == false) continue; } } catch(Exception e) { e.printStackTrace(); } } } package mx; import java.sql.*; import java.util.Vector; public class SQL { /** 保存数据库间隔,秒为单位 */ public static int flush_time = 30; /** 最后一次数据库连接数据时间 */ public static int last_conn; /** 定时连接数据库,秒为单位,防止长时间不连接中断 */ public static int conn_time = 18000; static String driver = "org.gjt.mm.mysql.Driver"; static String url = "jdbc:mysql://MYSQL_IP:MYSQL_PORT/MYSQL_DB?useUnicode=true&characterEncoding=utf-8"; static Connection con; static Statement stmt; static String user; static String pass; static String db; /** 写入内存缓存 */ private static Vector inBuf = new Vector(); /** 更新数据库缓存 */ private static Vector outBuf = new Vector(); public static void init(String ip, int port, String user, String pass, String db) { SQL.user = user; SQL.pass = pass; try { url = url.replaceAll("MYSQL_IP", ip); url = url.replaceAll("MYSQL_PORT", port + ""); url = url.replaceAll("MYSQL_DB", db); Class.forName(driver).newInstance(); con = DriverManager.getConnection(url, user, pass); DriverManager.setLoginTimeout(99999999); stmt = con.createStatement(); } catch (Exception e) { e.printStackTrace(); } } public static void Bye() { flush(); try { stmt.close(); con.close(); } catch (Exception E) { } } public static ResultSet Select(String SQLString) { ResultSet rs = null; try { if (con.isClosed()) { con = DriverManager.getConnection(url, user, pass); stmt = con.createStatement(); } rs = stmt.executeQuery(SQLString); return rs; } catch (Exception E) { System.out.println(E.getMessage()); return null; } } /** 写缓存 */ public static void Update(String sql) { inBuf.add(sql); } public static void execute(String SQLString) { try { if (con.isClosed()) { con = DriverManager.getConnection(url, user, pass); stmt = con.createStatement(); } stmt.executeUpdate(SQLString); } catch (Exception E) { } } /** 写数据库 */ public static void flush() { String sql; if (inBuf.size() == 0) { if (Time.now - last_conn > conn_time) { last_conn = Time.now; } return; } synchronized (inBuf) { outBuf = (Vector) inBuf.clone(); inBuf.clear(); } outBuf.clear(); } public static String encode(String str) { String res = ""; try { res = java.net.URLEncoder.encode(str, "UTF-8"); } catch (Exception e) { res = str; } finally { return res; } } public static String decode(String str) { String res = ""; try { res = java.net.URLDecoder.decode(str, "UTF-8"); } catch (Exception e) { res = str; } finally { return res; } } }