📄 serveclientthread.java.svn-base
字号:
/* * To change this template, choose Tools | Templates * and open the template in the editor. */package safechatserver;import java.sql.SQLException;import mytools.Packet;import mytools.DSA;import mytools.AES;import java.io.*;import java.net.*;import java.security.*;import java.util.logging.Level;import java.util.logging.Logger;import javax.crypto.BadPaddingException;import javax.crypto.IllegalBlockSizeException;import javax.swing.*;/** * 与客户端对话线程 * @author DJ尐舞 */public class ServeClientThread extends Thread { private Socket client; private InputStream in; private OutputStream out; private byte b[]; private int len; private String userName; private byte[] pubkey; private boolean[] listening; private DefaultListModel StateListM; private DefaultListModel UserListM; private AES serverAES; private TbModelTool tmt; /** * 客户端对话线程构造函数 * @param client 客户端套接字 * @param listening 服务器是否处于监听状态 * @param father 主窗口List管理器 * @param serverAES 服务器的AES加密工具对象 * @param tmt 数据库管理器对象 */ public ServeClientThread(Socket client, boolean[] listening, AES serverAES, TbModelTool tmt, DefaultListModel stateList, DefaultListModel userList) { this(client, listening, serverAES, tmt); StateListM = stateList; StateListM.addElement("客户端" + client.getInetAddress().getHostName() + "登陆"); UserListM = userList; } /** * 客户端对话线程构造函数 * @param client 客户端套接字 * @param listening 服务器是否处于监听状态 * @param serverAES 服务器的AES加密工具对象 * @param tmt 数据库管理器对象 */ public ServeClientThread(Socket client, boolean[] listening, AES serverAES, TbModelTool tmt) { this.listening = listening;//初始化监听状态 this.client = client; this.serverAES = serverAES; this.tmt = tmt; b = new byte[2048];//初始化用于接收客户端信息的字符串 try { //初始化用于接收客户端信息的字符串 in = this.client.getInputStream(); out = this.client.getOutputStream(); sendInfo("欢迎登陆");//当用户登陆自动发送欢迎信息 } catch (IOException ex) { //初始化客户端失败 ex.printStackTrace(); System.out.println("初始化客户端失败"); } } public void sendInfo(String info) throws IOException { sendInfo(info, Packet.Message); } public void sendInfo(String info, String Type) throws IOException { byte[] buf = info.getBytes(); Packet p = new Packet(Type, buf);//把b经过HASH打包 byte[] ep = serverAES.encrypt(Packet.ObjectToByte(p));//用AES加密包 out.write(ep); } public void endSocket() { try { sendInfo("服务器已关闭"); out.flush(); in.close(); out.close(); client.close(); } catch (IOException ex) { ex.printStackTrace(); } } /** * 注册用户 * @param userName 用户名 * @return 注册是否成功 */ private boolean register(String userName) { KeyPair keypair; PublicKey pubkey; PrivateKey prikey; byte[] encodedpubkey, encodedprikey; try { keypair = DSA.generatekey(); pubkey = keypair.getPublic(); prikey = keypair.getPrivate(); encodedpubkey = pubkey.getEncoded(); encodedprikey = prikey.getEncoded(); //发送密钥给用户 Packet p = new Packet(Packet.PrivateKey, encodedprikey);//把b经过HASH打包 byte[] ep = serverAES.encrypt(Packet.ObjectToByte(p));//用AES加密包 out.write(ep); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); Logger.getLogger(ServeClientThread.class.getName()).log(Level.SEVERE, null, ex); return false; } catch (IOException ie) { ie.printStackTrace(); return false; } if (tmt.addUser(userName, encodedpubkey)) {//把用户添加如数据库 System.out.println(DSA.byte2hex(encodedpubkey)); return true; } return false; } @Override public void run() { try { while (listening[0] && client.isConnected() == true) { if ((len = in.read(b)) != -1) { byte[] c = new byte[len]; for (int i = 0; i < len; i++) { c[i] = b[i]; } Packet p = (Packet) Packet.ByteToObject(serverAES.decrypt(c)); if (p.getType().equals(Packet.RegisterMessage)) {//注册消息处理 if (this.register(p.getStringContent())) { StateListM.addElement("客户端" + client.getInetAddress().getHostName() + "注册成功,用户名" + p.getStringContent() + "\n"); } else { StateListM.addElement("客户端" + client.getInetAddress().getHostName() + "注册失败\n"); } } else if (p.getType().equals(Packet.LoginMessage)) {//登陆消息处理 if (!p.isIntegrated()) { StateListM.addElement("客户端" + client.getInetAddress().getHostName() + "正在登陆但登陆信息完整性失败" + p.getStringContent() + "\n"); continue; } try { if (!p.isSignedRight(pubkey = tmt.getUserPubKey(p.getUserName()))) { StateListM.addElement("客户端" + client.getInetAddress().getHostName() + "正在登陆但签名验证失败" + p.getStringContent() + "\n"); sendInfo("身份验证失败", Packet.ResponeLogin); continue; } else { StateListM.addElement("用户" + p.getUserName() + "登陆成功,客户端为:" + client.getInetAddress().getHostName()); UserListM.addElement(p.getUserName()); this.userName = p.getUserName(); sendInfo("登陆成功", Packet.ResponeLogin); } } catch (SQLException ex) { ex.printStackTrace(); System.out.println("数据库访问失败"); } } else { if (!p.isIntegrated()) { StateListM.addElement("客户端" + client.getInetAddress().getHostName() + "发来一条信息,但完整性验证失败:" + p.getStringContent() + "\n"); } else if (!p.isSignedRight(pubkey)) { StateListM.addElement("客户端" + client.getInetAddress().getHostName() + "签名验证失败" + p.getStringContent() + "\n"); sendInfo("身份验证失败", Packet.ResponeLogin); } StateListM.addElement("用户" + userName + "说:" + p.getStringContent() + "\n"); } Thread.sleep(500); } else { throw new IOException(); } } } catch (InvalidKeyException ex) { Logger.getLogger(ServeClientThread.class.getName()).log(Level.SEVERE, null, ex); } catch (IllegalBlockSizeException ex) { Logger.getLogger(ServeClientThread.class.getName()).log(Level.SEVERE, null, ex); } catch (BadPaddingException ex) { Logger.getLogger(ServeClientThread.class.getName()).log(Level.SEVERE, null, ex); } catch (SocketException se) { StateListM.addElement("客户端" + client.getInetAddress().getHostName() + "已断开"); try { UserListM.removeElement(userName); } catch (Exception ex) { } } catch (IOException io) { io.printStackTrace(); StateListM.addElement("客户端" + client.getInetAddress().getHostName() + "已断开"); try { UserListM.removeElement(userName); } catch (Exception ex) { } } catch (InterruptedException ire) { ire.printStackTrace();// } finally {//// try {//// in.close();//// client.close();// StateListM.addElement("会话socket已断开!");// try {// UserListM.removeElement(userName);// } catch (Exception ex) {// }//// } catch (IOException ex) {//// Logger.getLogger(ServeClientThread.class.getName()).log(Level.SEVERE, null, ex);//// } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -