您的位置:首页 > 其它

登录 之 服务端响应

2013-02-18 11:45 141 查看
新年第一篇

前面讲到的关于通讯机制的实现是客户端,现在将服务端响应的部分实现予以展示

package com.net;

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.Hashtable;
import java.util.Iterator;
import java.util.Set;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class NioServer {
private ReadProperties rp = new ReadProperties();
private final String IP = rp.getProperty("ip");
private final int SERVERPORT = Integer.parseInt(rp
.getProperty("socketport"));
private final String ISACK = "ACK";
private final String ISNAK = "NAK!";
private final String SPLITSTR = rp.getProperty("split_string");

private ConnectionPool connpool=null;
private Connection conn=null;
private PreparedStatement pstmt=null;
private ResultSet rs = null;
private Hashtable<String,Integer> htMap=new Hashtable<String,Integer>();

// Selector selector;//选择器
// SelectionKey key;//key。 一个key代表一个Selector 在NIO通道上的注册,类似主键;//
// 取得这个Key后就可以对Selector在通道上进行操作
private ByteBuffer echoBuffer = ByteBuffer.allocate(1024);	// 通道数据缓冲区

public NioServer() {
this.initHashTable();
}

private void initHashTable(){
htMap.put("land", 1);
htMap.put("register", 2);
}

public void BuildNioServer() throws IOException {
// ///////////////////////////////////////////////////////
// ///////先对服务端的ServerSocket进行注册,注册到Selector ////
// ///////////////////////////////////////////////////////
ServerSocketChannel ssc = ServerSocketChannel.open();	// 新建NIO通道
ssc.configureBlocking(false);			// 使通道为非阻塞,false
ServerSocket ss = ssc.socket();			// 创建基于NIO通道的socket连接

ss.bind(new InetSocketAddress(IP, SERVERPORT));	// 新建socket通道的端口
Selector selector = Selector.open();			// 获取一个选择器
ssc.register(selector, SelectionKey.OP_ACCEPT);	// 将NIO通道绑定到选择器,当然绑定后分配的主键为skey

// //////////////////////////////////////////////////////////////////
// //// 接收客户端的连接Socket,并将此Socket也接连注册到Selector ////
// /////////////////////////////////////////////////////////////////
while (true) {
int num = selector.selectNow(); // 获取通道内是否有选择器的关心事件
if (num < 1) continue;
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> it = selectedKeys.iterator();// 获取通道内关心事件的集合

while (it.hasNext()) { 	// 遍历每个事件
try {
SelectionKey key = (SelectionKey) it.next();
// 有一个新联接接入事件,服务端事件
if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {
// 接收这个新连接
ServerSocketChannel serverChanel = (ServerSocketChannel) key.channel();
// 从serverSocketChannel中创建出与客户端的连接 socketChannel
SocketChannel sc = serverChanel.accept();
sc.configureBlocking(false);
// 把新连接注册到选择器
sc.register(selector,SelectionKey.OP_READ);
it.remove();
} else {
// 读客户端数据的事件,此时有客户端发数据过来,客户端事件
if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
// 读取数据
SocketChannel sc = (SocketChannel) key.channel();

if (sc.read(echoBuffer) > 0) {
echoBuffer.flip();
//System.out.println("limit:" + echoBuffer.limit());
byte[] content = new byte[echoBuffer.limit()];
echoBuffer.get(content);
String result = new String(content);
doPost(result, sc);
}
echoBuffer.clear();
it.remove();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

public void doPost(String str, SocketChannel sc) {
int firstIndex = str.indexOf(SPLITSTR);
int secondIndex = str.lastIndexOf(SPLITSTR);
String result = "";
if (firstIndex > 0) {
String name = str.substring(0, firstIndex);
String pswd = str.substring(firstIndex + SPLITSTR.length(),
secondIndex);
String respondStyle = str.substring(secondIndex + SPLITSTR.length());
if (name.length() != 0 && pswd.length() != 0 && respondStyle.length() != 0) {
switch (this.htMap.get(respondStyle)) {
case 1: // response of land
if (validateLogOn(name, pswd)) {
try {
result = ISACK + SPLITSTR
+ this.getLogOnUserInfo().getString("SName");
} catch (SQLException e) {
e.printStackTrace();
}
} else
result = ISNAK + SPLITSTR + "userName or passwd error";
break;
case 2: // response of register
if (validateUserExist(name)){
result = ISNAK + SPLITSTR + name + " has existed";
}else {
if (registerUserInfo(name, pswd)){
result = ISACK + SPLITSTR + name;
}else result = ISNAK + SPLITSTR + "regist " + name + " failed";
}
break;
default:
System.out.println("No response to [" + respondStyle + "].");
System.exit(1);
break;
}
} else {
System.out.println("At least one value of [name,passwd,respondStyle] is null.");
System.exit(1);
}
} else {
System.out.println("Can not receive split string.");
System.exit(1);
}

ByteBuffer bb = ByteBuffer.allocate(result.length() + 10);
bb.put(result.getBytes());
bb.flip();
try {
sc.write(bb);
} catch (IOException e) {
e.printStackTrace();
}
bb.clear();
}

private boolean validateLogOn(String name,String passwd){
connpool=ConnectionPool.getInstance();
conn=connpool.getConnection();
try {
pstmt = conn.prepareStatement("select * from Student where SAccounts = ? and SPasswd = ?;");
pstmt.setString(1, name);
pstmt.setString(2, passwd);
rs = pstmt.executeQuery();
if(rs.next()){
return true;
}else return false;
} catch (SQLException e) {
e.printStackTrace();
} finally {
connpool.releaseConnection(conn);
}
return false;
}

private ResultSet getLogOnUserInfo(){
return this.rs;
}

private boolean validateUserExist(String name){
connpool=ConnectionPool.getInstance();
conn=connpool.getConnection();
try {
pstmt = conn.prepareStatement("select * from Student where SAccounts = ?;");
pstmt.setString(1, name);
rs = pstmt.executeQuery();
if(rs.next()){
return true;
}else return false;
} catch (SQLException e) {
e.printStackTrace();
} finally {
connpool.releaseConnection(conn);
}
return false;
}

private boolean registerUserInfo(String name,String passwd){
connpool=ConnectionPool.getInstance();
conn=connpool.getConnection();
try {
pstmt = conn.prepareStatement("insert into Student(SID,SName,SAccounts,SPasswd) values(?,?,?,?);");
pstmt.setString(1, "id_"+name);
pstmt.setString(2, "test_"+name);
pstmt.setString(3, name);
pstmt.setString(4, passwd);
int rows=pstmt.executeUpdate();
if(rows != 0){
return true;
}else {
return false;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
connpool.releaseConnection(conn);
}
return false;
}

public static void main(String[] args) throws IOException {
NioServer ns = new NioServer();
ns.BuildNioServer();
}

}


为了提高数据库的连接性能,所以采用了连接池的设计:

定义连接池接口:ConnectionPoolInterface.java

package com.net;

import java.sql.Connection;

public interface ConnectionPoolInterface {
public Connection getConnection();
public void releaseConnection(Connection con);
}

实现连接代理:ConnectionHandler.java

package com.net;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;

public class ConnectionHandler implements InvocationHandler {
private Connection con;
private ConnectionPool pool;

public ConnectionHandler(ConnectionPool pool) {
this.pool = pool;
}

public Connection bind(Connection con) {
this.con = con;
// Connection proxyCon = (Connection) Proxy.newProxyInstance(con
// .getClass().getClassLoader(), con.getClass().getInterfaces(),
// this);
Connection proxyCon = (Connection) Proxy.newProxyInstance(
Connection.class.getClassLoader(),
new Class[] { Connection.class }, this);
return proxyCon;
}

public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
// TODO Auto-generated method stub
Object obj = null;
if ("close".equals(arg1.getName())) {
pool.releaseConnection(con);
} else {
obj = arg1.invoke(con, arg2);
}
return obj;
}
}

最后实现连接池:ConnectionPool.java

package com.net;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Vector;

public class ConnectionPool implements ConnectionPoolInterface {

private ReadProperties rp = new ReadProperties();
private static Vector<Connection> pool;
private static int POOL_MAX_SIZE = 0;
private static ConnectionPool conPool = null;
private static String DRIVER_NAME = "";
private static String URL_BASE = "";
private static String DB_NAME = "";
private static String SERVER_IP = "";
private static int SERVER_PORT = 0;
private static String DB_ADMIN_NAME = "";
private static String DB_ADMIN_PASSWD = "";

ConnectionPool() {
POOL_MAX_SIZE = Integer.parseInt(rp.getProperty("pool_max_size"));
DRIVER_NAME = rp.getProperty("driver_name");
URL_BASE = rp.getProperty("url_base");
DB_NAME = rp.getProperty("db_name");
SERVER_IP = rp.getProperty("server_ip");
SERVER_PORT = Integer.parseInt(rp.getProperty("server_port"));
DB_ADMIN_NAME = rp.getProperty("db_admin_name");
DB_ADMIN_PASSWD = rp.getProperty("db_admin_passwd");
}

public static ConnectionPool getInstance() {
if (conPool == null)
return new ConnectionPool();
else
return conPool;
}

public synchronized Connection getConnection() {
Connection con = null;
try {
if (pool == null)
pool = new Vector<Connection>();
if (pool.isEmpty()) {
con = ConnectionPool.createConnection();
} else {
int index = pool.size() - 1;
con = pool.get(index);
pool.remove(pool.get(index));
}
} catch (Exception e) {
e.printStackTrace();
}
ConnectionHandler ch = new ConnectionHandler(this);
return ch.bind(con);
}

public synchronized void releaseConnection(Connection con) {
if (pool.size() > POOL_MAX_SIZE) {
try {
if (con != null) {
con.close();
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
pool.add(con);
}
}

private static Connection createConnection() {
Connection con = null;
try {
Class.forName(DRIVER_NAME);
con = DriverManager.getConnection(URL_BASE + "//" + SERVER_IP + ":"
+ SERVER_PORT + "/" + DB_NAME, DB_ADMIN_NAME, DB_ADMIN_PASSWD);
} catch (ClassNotFoundException CNFex) {
CNFex.printStackTrace();
} catch (SQLException SQLex) {
SQLex.printStackTrace();
}
return con;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: