java在线聊天项目1.1版 ——开启多个客户端,分别实现注册和登录功能,使用客户端与服务端信息request机制,重构线程,将单独的登录和注册线程合并
实现效果图:
eclipse项目中初步整合之前的各个客户端和服务端的窗口与工具类,效果如下图:
已将注册服务器线程RegServer功能放到LoginServer中,使用客户端与服务端的request请求机制,根据请求是注册还是登录,分别进行相应response,客户端根据相应内容判断下一步操作。
发送信息的模式还较为原始,没有使用json方法,但gson包已经导入,支持发送键值对的字符串,及自动解析。
登录对话框LoginDialog类代码如下:
package com.swift.frame; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ConnectException; import java.net.Socket; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.TitledBorder; import com.google.gson.Gson; import com.swift.util.Center; public class LoginDialog extends JDialog { private JPasswordField passwordField_2; private JPasswordField passwordField_1; private JTextField textField_2; private JTextField textField; String request = null; String response = null; Socket s; DataOutputStream dos; DataInputStream dis; public static void main(String args[]) { JFrame.setDefaultLookAndFeelDecorated(true); JDialog.setDefaultLookAndFeelDecorated(true); try { UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel"); } catch (ClassNotFoundException e1) { e1.printStackTrace(); } catch (InstantiationException e1) { e1.printStackTrace(); } catch (IllegalAccessException e1) { e1.printStackTrace(); } catch (UnsupportedLookAndFeelException e1) { e1.printStackTrace(); } EventQueue.invokeLater(new Runnable() { public void run() { try { LoginDialog dialog = new LoginDialog(); dialog.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); dialog.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } public LoginDialog() { super(); setResizable(false); setTitle("在线聊天登录框"); getContentPane().setLayout(null); setBounds(100, 100, 427, 301);// 注册时高度为578,不注册是301 // 设置窗口居中 this.setLocation(Center.getPoint(this.getSize())); final JTextField textField_1 = new JTextField(); textField_1.setBounds(148, 90, 192, 42); getContentPane().add(textField_1); final JLabel label = new JLabel(); label.setText("帐 号"); label.setBounds(76, 102, 66, 18); getContentPane().add(label); final JLabel label_1 = new JLabel(); label_1.setText("密 码"); label_1.setBounds(76, 167, 66, 18); getContentPane().add(label_1); final JPasswordField passwordField = new JPasswordField(); passwordField.setBounds(148, 155, 192, 42); getContentPane().add(passwordField); final JButton button_1 = new JButton(); button_1.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { String phone = new String(textField_1.getText()).trim(); String password = new String(passwordField.getPassword()).trim(); if (!phone.equals("") && !password.equals("")) { try { request = "login"; dos.writeUTF(request); response = dis.readUTF(); if (response.equals("login")) { dos.writeUTF(phone); dos.writeUTF(password); String flag=dis.readUTF(); if(flag.equals("success")) { javax.swing.JOptionPane.showMessageDialog(LoginDialog.this, "登录成功"); }else if(flag.equals("fail")) { javax.swing.JOptionPane.showMessageDialog(LoginDialog.this, "登录失败"); } } } catch (IOException e1) { e1.printStackTrace(); } } else { javax.swing.JOptionPane.showMessageDialog(LoginDialog.this, "用户名密码必须填写..."); return; } } }); button_1.setText("登录"); button_1.setBounds(230, 222, 106, 36); getContentPane().add(button_1); final JButton button = new JButton(); button.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { if (LoginDialog.this.getHeight() == 301) { LoginDialog.this.setSize(427, 578); } else { LoginDialog.this.setSize(427, 301); } // 设置窗口不断居中 LoginDialog.this.setLocation(Center.getPoint(LoginDialog.this.getSize())); } }); button.setText("注册"); button.setBounds(76, 222, 106, 36); getContentPane().add(button); final JPanel panel = new JPanel(); panel.setLayout(null); panel.setBorder(new TitledBorder(null, "注册用户", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, null)); panel.setBounds(10, 278, 401, 226); getContentPane().add(panel); final JLabel label_2 = new JLabel(); label_2.setBounds(44, 41, 65, 18); label_2.setText("手机号:"); panel.add(label_2); textField = new JTextField(); textField.setBounds(115, 35, 225, 30); panel.add(textField); final JButton button_2 = new JButton(); button_2.setText("发送验证"); button_2.setBounds(243, 75, 97, 30); panel.add(button_2); textField_2 = new JTextField(); textField_2.setBounds(115, 104, 95, 30); panel.add(textField_2); final JLabel label_3 = new JLabel(); label_3.setText("验证码:"); label_3.setBounds(44, 110, 65, 18); panel.add(label_3); passwordField_1 = new JPasswordField(); passwordField_1.setBounds(115, 143, 231, 30); panel.add(passwordField_1); passwordField_2 = new JPasswordField(); passwordField_2.setBounds(115, 175, 231, 30); panel.add(passwordField_2); final JLabel label_4 = new JLabel(); label_4.setText("密 码:"); label_4.setBounds(44, 149, 65, 18); panel.add(label_4); final JLabel label_5 = new JLabel(); label_5.setText("验证密码:"); label_5.setBounds(44, 181, 65, 18); panel.add(label_5); final JButton button_3 = new JButton(); button_3.setBounds(47, 510, 97, 30); getContentPane().add(button_3); button_3.setText("放弃"); final JButton button_4 = new JButton(); button_4.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { String phone = textField.getText(); String password = null; String str1 = new String(passwordField_1.getPassword()).trim(); String str2 = new String(passwordField_2.getPassword()).trim(); if (!phone.equals("") && !str1.equals("") && !str2.equals("")) { if (str1.equals(str2)) { password = new String(passwordField_2.getPassword()).trim(); try { request = "reg"; dos.writeUTF(request); String response = dis.readUTF(); if (response.equals("reg")) { dos.writeUTF(phone); dos.writeUTF(password); } javax.swing.JOptionPane.showMessageDialog(LoginDialog.this, "注册成功..."); } catch (IOException e1) { e1.printStackTrace(); } } else { javax.swing.JOptionPane.showMessageDialog(LoginDialog.this, "输入密码不一致..."); System.out.println("输入密码不一致..."); passwordField_1.setText(""); passwordField_2.setText(""); } } else { javax.swing.JOptionPane.showMessageDialog(LoginDialog.this, "用户名密码必须填写..."); return; } } }); button_4.setBounds(262, 510, 97, 30); getContentPane().add(button_4); button_4.setText("注册用户"); connect(); this.addWindowListener(new WindowAdapter() { @Override public void windowClosed(WindowEvent e) { disconnect(); } }); } public void connect() { try { s = new Socket("127.0.0.1", 8888); System.out.println("一个客户端登陆中....!"); dos = new DataOutputStream(s.getOutputStream()); dis = new DataInputStream(s.getInputStream()); } catch (ConnectException e) { System.out.println("服务端异常........."); System.out.println("请确认服务端是否开启........."); } catch (IOException e) { e.printStackTrace(); } } public void disconnect() { try { if (dos != null) dos.close(); if (s != null) s.close(); } catch (IOException e) { e.printStackTrace(); } } }
登录与注册的服务端代 LoginServer类码如下:
package com.swift.server; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.swift.frame.LoginDialog; import com.swift.jdbc.DBAdd; import com.swift.jdbc.DBLogin; import com.swift.other.User; public class LoginServer { boolean started = false; ServerSocket ss = null; Socket s = null; String request = null; String response = null; public static void main(String[] args) { new LoginServer().fun(); } private void fun() { try { ss = new ServerSocket(8888); started = true; } catch (BindException e) { System.out.println("端口使用中......"); } catch (IOException e1) { e1.printStackTrace(); } try { while (started) { s = ss.accept(); System.out.println("a client connected success"); Client c = new Client(s); new Thread(c).start(); } } catch (EOFException e) { System.out.println("client has closed."); } catch (Exception e) { e.printStackTrace(); } finally { try { ss.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class Client implements Runnable { private Socket s; private DataInputStream dis; private DataOutputStream dos; private boolean connected = false; public Client(Socket s) { this.s = s; try { this.dis = new DataInputStream(s.getInputStream()); this.dos = new DataOutputStream(s.getOutputStream()); connected = true; } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { try { while (connected) { request = dis.readUTF(); response = request; dos.writeUTF(response); if (request.equals("login")) { String phone = dis.readUTF(); String password = dis.readUTF(); System.out.println(phone); System.out.println(password); User user = new User(phone, password); boolean login = DBLogin.login(user); if (login) { dos.writeUTF("success"); }else { dos.writeUTF("fail"); } } else if (request.equals("reg")) { String phone = dis.readUTF(); String password = dis.readUTF(); System.out.println(phone); System.out.println(password); User user = new User(phone, password); DBAdd.add(user); } } } catch (SocketException e) { System.out.println("一个登陆窗已经关闭...."); } catch (IOException e) { e.printStackTrace(); } finally { if (s != null) { try { s.close(); } catch (IOException e) { e.printStackTrace(); } } if (dis != null) { try { dis.close(); } catch (IOException e) { e.printStackTrace(); } } if (dos != null) { try { dos.close(); } catch (IOException e) { e.printStackTrace(); } } } } } }
连接数据库工具类DBUtil类代码:
package com.swift.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class DBUtil { public static Connection getConn() { Connection conn=null; try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { String url="jdbc:mysql://localhost:3306/sw_database"; String user="root"; String password="root"; conn=DriverManager.getConnection(url, user, password); } catch (SQLException e) { e.printStackTrace(); } return conn; } public static void closeAll(Connection conn,PreparedStatement ps,ResultSet rs) { if(conn!=null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } if(ps!=null) { try { ps.close(); } catch (SQLException e) { e.printStackTrace(); } } if(rs!=null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
添加到数据库的类DBAdd代码:
package com.swift.jdbc; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import com.swift.other.User; public class DBAdd { public static void add(User user) { String phone = user.getUsername(); String password = user.getPassword(); Connection conn = DBUtil.getConn(); PreparedStatement ps=null; try { ps = conn.prepareStatement("insert into sw_user(username,password) values(?,?)"); ps.setString(1, phone); ps.setString(2, password); int count = ps.executeUpdate(); if (count == 1) { System.out.println("用户添加成功"); } else { System.out.println("用户添加失败"); } } catch (SQLException e) { e.printStackTrace(); }finally { DBUtil.closeAll(conn, ps, null); } } }
登录时查询数据库DBLogin类代码:
package com.swift.jdbc; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import com.swift.other.User; public class DBLogin { public static boolean login(User user) { Connection conn=DBUtil.getConn(); PreparedStatement ps=null; ResultSet rs=null; try { ps=conn.prepareStatement("select * from sw_user where username=? and password=?"); ps.setString(1, user.getUsername()); ps.setString(2, user.getPassword()); rs=ps.executeQuery(); if(rs.next()) { return true; } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } DBUtil.closeAll(conn, ps, rs); return false; } }
两个辅助类User类和居中类Center
package com.swift.other; public class User { private int id; private String username; private String password; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public User(int id, String username, String password) { this.id = id; this.username = username; this.password = password; } public User() { super(); } public User(String username, String password) { this.username = username; this.password = password; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", password=" + password + "]"; } }
Center类:
package com.swift.util; import java.awt.Dimension; import java.awt.Point; import java.awt.Toolkit; public class Center { public static Point getPoint(int width,int height) { Toolkit toolkit=Toolkit.getDefaultToolkit();//应该是单例 int screenW=toolkit.getScreenSize().width; int screenH=toolkit.getScreenSize().height; int x=(screenW-width)/2; int y=(screenH-height)/2; Point p=new Point(x,y); return p; } //函数的重载,参数是包装类尺寸——Dimension public static Point getPoint(Dimension d) { Point p=getPoint(d.width,d.height); return p; } }
Never waste time any more, Never old man be a yong man