java 通过TCP\UDP 协议实现多人聊天,点对点,文件传送-----分服务器端和客户端

时间:2024-03-12 17:39:27

java 通过TCP\UDP 协议实现多人聊天,点对点,文件传送-----分服务器端和客户端

 

  启动界面如下图:

 

 

 

首先启动服务器:

 

 

客户端登陆,登陆成功后为:

 

默认发送是全部用户,是多人发送。  当在边列表里面选择了用户后,可以与此用户建立点对点链接进行聊天,可以发送文件。

 

 

 

 用户在线离线状态会实时更新,如果离线,则存为离线消息。当下次上线的时候,会接受到离线消息

 

 

 

 

 从一个用户接受文件的同时,还可以接受从服务器发过来的文件

 

接受文件完成后,显示记录,并显示保存目录

 

消息发送演示

 

 服务器端代码:

   1 import sun.misc.BASE64Encoder;
   2 
   3 import java.awt.BorderLayout;
   4 import java.awt.Color;
   5 import java.awt.GridLayout;
   6 import java.awt.Toolkit;
   7 import java.awt.event.ActionEvent;
   8 import java.awt.event.ActionListener;
   9 import java.awt.event.WindowAdapter;
  10 import java.awt.event.WindowEvent;
  11 import java.io.*;
  12 import java.net.BindException;
  13 import java.net.ServerSocket;
  14 import java.net.Socket;
  15 import java.security.MessageDigest;
  16 import java.security.NoSuchAlgorithmException;
  17 import java.sql.Connection;
  18 import java.sql.DriverManager;
  19 import java.sql.ResultSet;
  20 import java.sql.Statement;
  21 import java.text.SimpleDateFormat;
  22 import java.util.ArrayList;
  23 import java.util.Date;
  24 import java.util.StringTokenizer;
  25 
  26 import javax.swing.DefaultListModel;
  27 import javax.swing.JButton;
  28 import javax.swing.JFileChooser;
  29 import javax.swing.JFrame;
  30 import javax.swing.JLabel;
  31 import javax.swing.JList;
  32 import javax.swing.JOptionPane;
  33 import javax.swing.JPanel;
  34 import javax.swing.JScrollPane;
  35 import javax.swing.JSplitPane;
  36 import javax.swing.JTextArea;
  37 import javax.swing.JTextField;
  38 import javax.swing.border.TitledBorder;
  39 import javax.swing.event.ListSelectionEvent;
  40 import javax.swing.event.ListSelectionListener;
  41 
  42 public class Server {
  43 
  44     private JFrame frame;
  45     private JTextArea contentArea;
  46     private JTextField txt_message;
  47     private JTextField txt_max;
  48     private JTextField txt_port;
  49     private JButton btn_start;
  50     private JButton btn_stop;
  51     private JButton btn_send;
  52     private JButton btn_send_file;
  53     private JPanel northPanel;
  54     private JPanel southPanel;
  55     private JPanel sendPanel;
  56     private JScrollPane rightPanel;
  57     private JScrollPane leftPanel;
  58     private JScrollPane rightPanel2;
  59     private JSplitPane centerSplit;
  60     private JSplitPane centerSplit2;
  61     private JList userList;
  62     private JList all_userList;
  63     private DefaultListModel listModel;
  64     private static DefaultListModel all_listModel;
  65 
  66     private ServerSocket serverSocket;
  67     private ServerThread serverThread;
  68     private ArrayList<ClientThread> clients;//客户线程数组
  69 
  70     private boolean isStart = false;//标志服务器是否启动或关闭
  71 
  72     private int sendfor_who = 0;//监听左边jlist,保存给哪个用户发消息
  73 
  74     // 主方法,程序执行入口
  75     public static void main(String[] args) {
  76 
  77         new Server();
  78 
  79         try {
  80             Connection con = null; //定义一个MYSQL链接对象
  81             Class.forName("com.mysql.jdbc.Driver").newInstance();//MYSQL驱动
  82             con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/server_db", "root", "root"); //链接本地MYSQL
  83             Statement stmt; //创建声明
  84             stmt = con.createStatement();
  85 
  86         } catch (Exception e) {
  87             System.out.print("MYSQL ERROR:" + e.getMessage());
  88         }
  89     }
  90 
  91     /**利用MD5进行加密
  92      * @param str  待加密的字符串
  93      * @return  加密后的字符串
  94      * @throws NoSuchAlgorithmException  没有这种产生消息摘要的算法
  95      * @throws UnsupportedEncodingException
  96      */
  97     public String EncoderByMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
  98         //确定计算方法
  99         MessageDigest md5=MessageDigest.getInstance("MD5");
 100         BASE64Encoder base64en = new BASE64Encoder();
 101         //加密后的字符串
 102         String newstr=base64en.encode(md5.digest(str.getBytes("utf-8")));
 103         return newstr;
 104     }
 105 
 106     /**判断用户密码是否正确
 107      * @param newpasswd  用户输入的密码
 108      * @param oldpasswd  数据库中存储的密码--用户密码的摘要
 109      * @return
 110      * @throws NoSuchAlgorithmException
 111      * @throws UnsupportedEncodingException
 112      */
 113     public boolean checkpassword(String newpasswd,String oldpasswd) throws NoSuchAlgorithmException, UnsupportedEncodingException{
 114         if(EncoderByMd5(newpasswd).equals(oldpasswd))
 115             return true;
 116         else
 117             return false;
 118     }
 119 
 120     /**
 121      * 刚服务器突然关闭时,把所有用户状态置为离线
 122      */
 123     public void set_user_state_off() {
 124         try {
 125             Connection con = null; //定义一个MYSQL链接对象
 126             Class.forName("com.mysql.jdbc.Driver").newInstance();//MYSQL驱动
 127             con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/server_db", "root", "root"); //链接本地MYSQL
 128             Statement stmt; //创建声明
 129             stmt = con.createStatement();
 130 
 131             int id = 0;
 132             String selectSql = "UPDATE user SET state = 0";
 133             stmt.executeUpdate(selectSql);
 134         } catch (Exception e) {
 135             System.out.print("MYSQL ERROR:" + e.getMessage());
 136         }
 137     }
 138 
 139     /**
 140      * 更新用户状态
 141      */
 142     public void user_name_update() {
 143 
 144         try {
 145             Connection con = null; //定义一个MYSQL链接对象
 146             Class.forName("com.mysql.jdbc.Driver").newInstance();//MYSQL驱动
 147             con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/server_db", "root", "root"); //链接本地MYSQL
 148             Statement stmt; //创建声明
 149             stmt = con.createStatement();
 150 
 151             all_listModel.removeAllElements();
 152             all_listModel.addElement("全部用户");
 153 
 154             String username_db;
 155             int state = 0;
 156             //查询用户名
 157             String selectSql = "SELECT * FROM user";
 158             ResultSet selectRes = stmt.executeQuery(selectSql);
 159             while (selectRes.next()) { //循环输出结果集
 160                 username_db = selectRes.getString("username");
 161                 state = selectRes.getInt("state");
 162                 if (state == 1) {
 163                     all_listModel.addElement(username_db + "---(在线)");
 164                 }
 165 
 166             }
 167 
 168             selectRes = stmt.executeQuery(selectSql);
 169             while (selectRes.next()) { //循环输出结果集
 170                 username_db = selectRes.getString("username");
 171                 state = selectRes.getInt("state");
 172                 if (state == 0) {
 173                     all_listModel.addElement(username_db + "---(离线)");
 174                 }
 175 
 176             }
 177         } catch (Exception e) {
 178             System.out.print("MYSQL ERROR:" + e.getMessage());
 179         }
 180 
 181     }
 182 
 183     /**
 184      * 执行消息发送
 185      */
 186     public void send() {
 187         if (!isStart) {
 188             JOptionPane.showMessageDialog(frame, "服务器还未启动,不能发送消息!", "错误",
 189                     JOptionPane.ERROR_MESSAGE);
 190             return;
 191         }
 192 //        if (clients.size() == 0) {
 193 //            JOptionPane.showMessageDialog(frame, "没有用户在线,不能发送消息!", "错误",
 194 //                    JOptionPane.ERROR_MESSAGE);
 195 //            return;
 196 //        }
 197         String message = txt_message.getText().trim();
 198         if (message == null || message.equals("")) {
 199             JOptionPane.showMessageDialog(frame, "消息不能为空!", "错误",
 200                     JOptionPane.ERROR_MESSAGE);
 201             return;
 202         }
 203         sendServerMessage(message, sendfor_who);// 群发服务器消息
 204         //contentArea.append("对  "+listModel.getElementAt(sendfor_who)+"  说:" + txt_message.getText() + "\r\n");
 205         txt_message.setText(null);
 206     }
 207 
 208     // 构造放法
 209     public Server() {
 210         SelecTry selectIndex = new SelecTry();
 211         frame = new JFrame("服务器");
 212         contentArea = new JTextArea();
 213         contentArea.setEditable(false);
 214         contentArea.setForeground(Color.blue);
 215         txt_message = new JTextField();
 216         txt_max = new JTextField("30");
 217         txt_port = new JTextField("6666");
 218         btn_start = new JButton("启动");
 219         btn_stop = new JButton("停止");
 220         btn_send = new JButton("发送");
 221         btn_send_file = new JButton("文件");
 222         btn_stop.setEnabled(false);
 223         listModel = new DefaultListModel();
 224         all_listModel = new DefaultListModel();
 225         //listModel.addElement("全部用户");
 226         userList = new JList(all_listModel);//listModel
 227         userList.addListSelectionListener(selectIndex);
 228 
 229         user_name_update();//更新用户状态
 230 
 231 //        all_userList = new JList(all_listModel);
 232 
 233         southPanel = new JPanel(new BorderLayout());
 234         sendPanel = new JPanel(new BorderLayout());
 235         southPanel.setBorder(new TitledBorder("写消息"));
 236         southPanel.add(txt_message, "Center");
 237         sendPanel.add(btn_send, BorderLayout.NORTH);
 238         sendPanel.add(btn_send_file, BorderLayout.SOUTH);
 239 
 240         southPanel.add(sendPanel, "East");
 241 
 242         leftPanel = new JScrollPane(userList);
 243         leftPanel.setBorder(new TitledBorder("用户列表"));
 244 
 245 //        rightPanel2 = new JScrollPane(all_userList);
 246 //        rightPanel2.setBorder(new TitledBorder("全部用户"));
 247 
 248         rightPanel = new JScrollPane(contentArea);
 249         rightPanel.setBorder(new TitledBorder("消息显示区"));
 250 
 251         centerSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel,
 252                 rightPanel);
 253         centerSplit.setDividerLocation(150);
 254 
 255 //        centerSplit2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, centerSplit,
 256 //                rightPanel2);
 257 //        centerSplit2.setDividerLocation(450);
 258 
 259         northPanel = new JPanel();
 260         northPanel.setLayout(new GridLayout(1, 6));
 261         northPanel.add(new JLabel("          人数上限"));
 262         northPanel.add(txt_max);
 263         northPanel.add(new JLabel("           端口"));
 264         northPanel.add(txt_port);
 265         northPanel.add(btn_start);
 266         northPanel.add(btn_stop);
 267         northPanel.setBorder(new TitledBorder("配置信息"));
 268 
 269         frame.setLayout(new BorderLayout());
 270         frame.add(northPanel, "North");
 271         frame.add(centerSplit, "Center");
 272         //frame.add(rightPanel2,BorderLayout.EAST);
 273         frame.add(southPanel, "South");
 274         frame.setSize(600, 400);
 275         //frame.setSize(Toolkit.getDefaultToolkit().getScreenSize());//设置全屏
 276         int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;
 277         int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;
 278         frame.setLocation((screen_width - frame.getWidth()) / 2,
 279                 (screen_height - frame.getHeight()) / 2);
 280         frame.setVisible(true);
 281 
 282         // 关闭窗口时事件
 283         frame.addWindowListener(new WindowAdapter() {
 284             public void windowClosing(WindowEvent e) {
 285                 if (isStart) {
 286                     closeServer();// 关闭服务器
 287                 }
 288                 System.exit(0);// 退出程序
 289             }
 290         });
 291 
 292         // 文本框按回车键时事件
 293         txt_message.addActionListener(new ActionListener() {
 294             public void actionPerformed(ActionEvent e) {
 295                 send();
 296             }
 297         });
 298 
 299         // 单击发送按钮时事件
 300         btn_send.addActionListener(new ActionListener() {
 301             public void actionPerformed(ActionEvent arg0) {
 302                 send();
 303             }
 304         });
 305 
 306         //单机文件按钮时事件
 307         btn_send_file.addActionListener(new ActionListener() {
 308             public void actionPerformed(ActionEvent arg0) {
 309                 //文件选择对话框启动,当选择了文件以后给每一个client发送文件
 310                 JFileChooser sourceFileChooser = new JFileChooser(".");
 311                 sourceFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
 312                 int status = sourceFileChooser.showOpenDialog(frame);
 313                 File sourceFile = new File(sourceFileChooser.getSelectedFile().getPath());
 314                 //服务器text area提示
 315                 contentArea.append("发送文件:" + sourceFile.getName() + "\r\n");
 316                 for (int i = clients.size() - 1; i >= 0; i--) {
 317                     SendFileThread sendFile = new SendFileThread(frame, clients.get(i).socket, "服务器", sourceFileChooser, status);
 318                     sendFile.start();
 319                     //client端提示
 320                     clients.get(i).getWriter().println("服务器发送一个文件:" + sourceFile.getName() + "(多人发送)");
 321                     clients.get(i).getWriter().flush();
 322                 }
 323 
 324             }
 325         });
 326 
 327         // 单击启动服务器按钮时事件
 328         btn_start.addActionListener(new ActionListener() {
 329             public void actionPerformed(ActionEvent e) {
 330 
 331                 if (isStart) {
 332                     JOptionPane.showMessageDialog(frame, "服务器已处于启动状态,不要重复启动!",
 333                             "错误", JOptionPane.ERROR_MESSAGE);
 334                     return;
 335                 }
 336                 int max;//人数
 337                 int port;//端口号
 338                 try {
 339                     try {
 340                         max = Integer.parseInt(txt_max.getText());
 341                     } catch (Exception e1) {
 342                         throw new Exception("人数上限为正整数!");
 343                     }
 344                     if (max <= 0) {
 345                         throw new Exception("人数上限为正整数!");
 346                     }
 347                     try {
 348                         port = Integer.parseInt(txt_port.getText());
 349                     } catch (Exception e1) {
 350                         throw new Exception("端口号为正整数!");
 351                     }
 352                     if (port <= 0) {
 353                         throw new Exception("端口号 为正整数!");
 354                     }
 355                     serverStart(max, port);
 356                     contentArea.append("服务器已成功启动!   人数上限:" + max + ",  端口:" + port
 357                             + "\r\n");
 358                     JOptionPane.showMessageDialog(frame, "服务器成功启动!");
 359                     btn_start.setEnabled(false);
 360                     txt_max.setEnabled(false);
 361                     txt_port.setEnabled(false);
 362                     btn_stop.setEnabled(true);
 363                     listModel.addElement("全部用户");
 364                     user_name_update();
 365                 } catch (Exception exc) {
 366                     JOptionPane.showMessageDialog(frame, exc.getMessage(),
 367                             "错误", JOptionPane.ERROR_MESSAGE);
 368                 }
 369             }
 370         });
 371 
 372         // 单击停止服务器按钮时事件
 373         btn_stop.addActionListener(new ActionListener() {
 374             public void actionPerformed(ActionEvent e) {
 375                 if (!isStart) {
 376                     JOptionPane.showMessageDialog(frame, "服务器还未启动,无需停止!", "错误",
 377                             JOptionPane.ERROR_MESSAGE);
 378                     return;
 379                 }
 380                 try {
 381                     closeServer();
 382                     btn_start.setEnabled(true);
 383                     txt_max.setEnabled(true);
 384                     txt_port.setEnabled(true);
 385                     btn_stop.setEnabled(false);
 386                     contentArea.append("服务器成功停止!\r\n");
 387                     JOptionPane.showMessageDialog(frame, "服务器成功停止!");
 388                 } catch (Exception exc) {
 389                     JOptionPane.showMessageDialog(frame, "停止服务器发生异常!", "错误",
 390                             JOptionPane.ERROR_MESSAGE);
 391                 }
 392             }
 393         });
 394     }
 395 
 396     /**
 397      * 监听左边jlist选择的是哪一个用户
 398      */
 399     class SelecTry implements ListSelectionListener {
 400         int change = 0, who;
 401 
 402         public void valueChanged(ListSelectionEvent e) {
 403             //System.out.println("you selected:"+listModel.getElementAt(userList.getSelectedIndex()));
 404             sendfor_who = userList.getSelectedIndex();
 405         }
 406 
 407     }
 408 
 409     /**
 410      * 找回密码模块
 411      *
 412      * @param username
 413      * @param youxiang
 414      * @param new_password
 415      * @return
 416      */
 417     public int user_forget(String username, String youxiang, String new_password) {
 418         try {
 419             Connection con = null; //定义一个MYSQL链接对象
 420             Class.forName("com.mysql.jdbc.Driver").newInstance();//MYSQL驱动
 421             con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/server_db", "root", "root"); //链接本地MYSQL
 422             Statement stmt; //创建声明
 423             stmt = con.createStatement();
 424 
 425             String codingpassword = EncoderByMd5(new_password);
 426 
 427             //查询数据,不能有相同的用户名
 428             String selectSql = "SELECT * FROM user";
 429             ResultSet selectRes = stmt.executeQuery(selectSql);
 430             while (selectRes.next()) { //循环输出结果集
 431                 int userid = selectRes.getInt("Id");
 432                 String username_db = selectRes.getString("username");
 433                 String youxiang_db = selectRes.getString("youxiang");
 434                 if (username.equals(username_db)) {
 435                     if (youxiang_db.equals(youxiang)) {
 436                         //更新一条数据
 437                         String updateSql = "UPDATE user SET password = \'" + codingpassword + "\' WHERE Id = " + userid + "";
 438                         long updateRes = stmt.executeUpdate(updateSql);
 439                         return 1;
 440                     }
 441 
 442                 }
 443             }
 444             return 0;
 445         } catch (Exception e) {
 446             System.out.print("MYSQL ERROR:" + e.getMessage());
 447         }
 448         return 0;
 449     }
 450 
 451 
 452     /**
 453      * 注册模块
 454      *
 455      * @param username
 456      * @param password
 457      * @param youxiang
 458      * @return
 459      */
 460     public int user_register(String username, String password, String youxiang) {
 461 
 462         try {
 463             Connection con = null; //定义一个MYSQL链接对象
 464             Class.forName("com.mysql.jdbc.Driver").newInstance();//MYSQL驱动
 465             con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/server_db", "root", "root"); //链接本地MYSQL
 466             Statement stmt; //创建声明
 467             stmt = con.createStatement();
 468 
 469             String codingPassword = EncoderByMd5(password);
 470 
 471             //查询数据,不能有相同的用户名
 472             String selectSql = "SELECT * FROM user";
 473             ResultSet selectRes = stmt.executeQuery(selectSql);
 474             while (selectRes.next()) { //循环输出结果集
 475                 String username_db = selectRes.getString("username");
 476                 if (username.equals(username_db)) {
 477                     return 2;
 478                 }
 479             }
 480             //新增一条数据
 481             stmt.executeUpdate("INSERT INTO user (username, password,youxiang) VALUES (\'" + username + "\', \'" + codingPassword + "\',\'" + youxiang + "\')");
 482             all_listModel.addElement(username);
 483             return 1;
 484         } catch (Exception e) {
 485             System.out.print("MYSQL ERROR:" + e.getMessage());
 486         }
 487         return 0;
 488     }
 489 
 490     /**
 491      * 当有用户下线时,在服务器改变状态
 492      *
 493      * @param name
 494      * @return
 495      */
 496     public int user_offLine(String name) {
 497         try {
 498             Connection con = null; //定义一个MYSQL链接对象
 499             Class.forName("com.mysql.jdbc.Driver").newInstance();//MYSQL驱动
 500             con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/server_db", "root", "root"); //链接本地MYSQL
 501             Statement stmt; //创建声明
 502             stmt = con.createStatement();
 503 
 504             //
 505             String username_fromDb;
 506             int id = 0;
 507             String selectSql = "SELECT * FROM user";
 508             ResultSet selectRes = stmt.executeQuery(selectSql);
 509             while (selectRes.next()) { //循环输出结果集
 510                 username_fromDb = selectRes.getString("username");
 511                 id = selectRes.getInt("Id");
 512                 if (name.equals(username_fromDb)) {
 513                     selectSql = "UPDATE user SET state = 0  WHERE Id = " + id + "";
 514                     stmt.executeUpdate(selectSql);
 515                     selectSql = "UPDATE user SET serverPort = 0  WHERE Id = " + id + "";
 516                     stmt.executeUpdate(selectSql);
 517                     selectSql = "UPDATE user SET ipAdres = \'\'  WHERE Id = " + id + "";
 518                     stmt.executeUpdate(selectSql);
 519                     return 1;
 520                 }
 521             }
 522         } catch (Exception e) {
 523             System.out.print("MYSQL ERROR:" + e.getMessage());
 524         }
 525         return 0;
 526     }
 527 
 528     /**
 529      * 登陆模块
 530      *
 531      * @param username
 532      * @param password
 533      * @return
 534      */
 535     public int user_login(String username, String password,int serverPort,String myIP) {
 536         try {
 537             Connection con = null; //定义一个MYSQL链接对象
 538             Class.forName("com.mysql.jdbc.Driver").newInstance();//MYSQL驱动
 539             con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/server_db", "root", "root"); //链接本地MYSQL
 540             Statement stmt; //创建声明
 541             stmt = con.createStatement();
 542 
 543 
 544             //
 545             String username_fromDb;
 546             String password_fromDb;
 547             String codingNewPassword;
 548             int state = 0, id = 0;
 549             String selectSql = "SELECT * FROM user";
 550             ResultSet selectRes = stmt.executeQuery(selectSql);
 551             while (selectRes.next()) { //循环输出结果集
 552                 username_fromDb = selectRes.getString("username");
 553                 password_fromDb = selectRes.getString("password");
 554                 codingNewPassword = EncoderByMd5(password);
 555                 id = selectRes.getInt("Id");
 556                 state = selectRes.getInt("state");
 557                 if (username.equals(username_fromDb) && codingNewPassword.equals(password_fromDb)) {
 558                     if (state == 0) {
 559                         selectSql = "UPDATE user SET state = 1  WHERE Id = " + id + "";
 560                         stmt.executeUpdate(selectSql);
 561                         selectSql = "UPDATE user SET serverPort = " + serverPort + "  WHERE Id = " + id + "";
 562                         stmt.executeUpdate(selectSql);
 563                         selectSql = "UPDATE user SET ipAdres = \'" + myIP + "\'  WHERE Id = " + id + "";
 564                         stmt.executeUpdate(selectSql);
 565                         return 1;//还没有登陆,可以登陆
 566                     } else {
 567                         return 2;//已登陆状态,无法登陆
 568                     }
 569 
 570                 }
 571             }
 572         } catch (Exception e) {
 573             System.out.print("MYSQL ERROR:" + e.getMessage());
 574         }
 575         return 0;
 576     }
 577 
 578     /**
 579      * 启动服务器
 580      *
 581      * @param max
 582      * @param port
 583      * @throws java.net.BindException
 584      */
 585     public void serverStart(int max, int port) throws java.net.BindException {
 586         try {
 587             clients = new ArrayList<ClientThread>();
 588             serverSocket = new ServerSocket(port);
 589             serverThread = new ServerThread(serverSocket, max);
 590             serverThread.start();
 591             isStart = true;
 592         } catch (BindException e) {
 593             isStart = false;
 594             throw new BindException("端口号已被占用,请换一个!");
 595         } catch (Exception e1) {
 596             e1.printStackTrace();
 597             isStart = false;
 598             throw new BindException("启动服务器异常!");
 599         }
 600     }
 601 
 602     /**
 603      * 关闭服务器
 604      */
 605     @SuppressWarnings("deprecation")
 606     public void closeServer() {
 607         try {
 608             if (serverThread != null)
 609                 serverThread.stop();// 停止服务器线程
 610 
 611             for (int i = clients.size() - 1; i >= 0; i--) {
 612                 // 给所有在线用户发送关闭命令
 613                 clients.get(i).getWriter().println("CLOSE");
 614                 clients.get(i).getWriter().flush();
 615                 // 释放资源
 616                 clients.get(i).stop();// 停止此条为客户端服务的线程
 617                 clients.get(i).reader.close();
 618                 clients.get(i).writer.close();
 619                 clients.get(i).socket.close();
 620                 clients.remove(i);
 621             }
 622             if (serverSocket != null) {
 623                 serverSocket.close();// 关闭服务器端连接
 624             }
 625             listModel.removeAllElements();// 清空用户列表
 626             isStart = false;
 627             set_user_state_off();
 628             user_name_update();
 629         } catch (IOException e) {
 630             e.printStackTrace();
 631             isStart = true;
 632         }
 633     }
 634 
 635     /**
 636      * 群发服务器消息
 637      *
 638      * @param message
 639      * @param who
 640      */
 641     public void sendServerMessage(String message, int who) {
 642         if (who == 0) {
 643             StringTokenizer stringTokenizer;
 644             int flag = 0;
 645             for (int i = all_listModel.size(); i > 0; i--) {
 646                 flag = 0;
 647                 String msg = all_listModel.getElementAt(i - 1) + "";
 648                 stringTokenizer = new StringTokenizer(
 649                         msg, "---");
 650                 String user_name = stringTokenizer.nextToken();
 651                 for (int j = clients.size() - 1; j >= 0; j--) {
 652                     if (user_name.equals(clients.get(j).getUser().getName())) {
 653                         clients.get(j).getWriter().println("服务器对你说   " + message);
 654                         clients.get(j).getWriter().flush();
 655                         flag = 1;//该用户在线状态,已发出去
 656                         break;
 657                     }
 658                 }
 659                 if (flag == 0) {
 660                     //用户离线状态,则留言
 661                     send_messageTo_board("服务器", user_name, message);
 662                 }
 663             }
 664             contentArea.append("对  全部用户   发送:" + message + "\r\n");
 665         } else {
 666             int flag = 0;
 667             String msg = "" + all_listModel.getElementAt(who);
 668             StringTokenizer stringTokenizer = new StringTokenizer(
 669                     msg, "---");
 670             String user_name = stringTokenizer.nextToken();
 671             for (int i = clients.size() - 1; i >= 0; i--) {
 672                 if (user_name.equals(clients.get(i).getUser().getName())) {
 673                     clients.get(i).getWriter().println("服务器对你说   " + message);
 674                     clients.get(i).getWriter().flush();
 675                     flag = 1;//该用户在线状态,已发出去
 676                     break;
 677                 }
 678             }
 679             if (flag == 0) {
 680 //                JOptionPane.showMessageDialog(frame, "该用户不在线,已存为留言板!", "错误",
 681 //                        JOptionPane.ERROR_MESSAGE);
 682                 send_messageTo_board("服务器", user_name, message);
 683                 contentArea.append("对  " + user_name + "  留言:" + message + "\r\n");
 684             } else {
 685                 contentArea.append("对  " + user_name + "  说:" + message + "\r\n");
 686             }
 687         }
 688 
 689     }
 690 
 691     /**
 692      * 用户不在线时,离线消息保存到服务器里面
 693      * @param send_from
 694      * @param send_for
 695      * @param message
 696      * @return
 697      */
 698     public int send_messageTo_board(String send_from, String send_for, String message) {
 699         SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
 700         String msg = send_from + "#" + df.format(new Date()) + "#" + message + "#";
 701         try {
 702             Connection con = null; //定义一个MYSQL链接对象
 703             Class.forName("com.mysql.jdbc.Driver").newInstance();//MYSQL驱动
 704             con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/server_db", "root", "root"); //链接本地MYSQL
 705             Statement stmt; //创建声明
 706             stmt = con.createStatement();
 707 
 708             //查询数据,不能有相同的用户名
 709             String selectSql = "SELECT * FROM user";
 710             ResultSet selectRes = stmt.executeQuery(selectSql);
 711             while (selectRes.next()) { //循环输出结果集
 712                 int Id = selectRes.getInt("Id");
 713                 String username_db = selectRes.getString("username");
 714                 if (send_for.equals(username_db)) {
 715                     String old_message = selectRes.getString("message");
 716                     String updateSql = "UPDATE user SET message = \'" + old_message + msg + "\' WHERE Id = " + Id + "";
 717                     stmt.executeUpdate(updateSql);
 718                     return 1;
 719                 }
 720             }
 721             return 0;
 722         } catch (Exception e) {
 723             System.out.print("MYSQL ERROR:" + e.getMessage());
 724         }
 725         return 0;
 726     }
 727 
 728     /**
 729      * 服务器线程
 730      */
 731     class ServerThread extends Thread {
 732         private ServerSocket serverSocket;
 733         private int max;// 人数上限
 734 
 735         // 服务器线程的构造方法
 736         public ServerThread(ServerSocket serverSocket, int max) {
 737             this.serverSocket = serverSocket;
 738             this.max = max;
 739         }
 740 
 741         public void run() {
 742             while (true) {// 不停的等待客户端的链接
 743                 try {
 744                     Socket socket = serverSocket.accept();
 745                     if (clients.size() == max) {// 如果已达人数上限
 746                         BufferedReader r = new BufferedReader(
 747                                 new InputStreamReader(socket.getInputStream()));
 748                         PrintWriter w = new PrintWriter(socket
 749                                 .getOutputStream());
 750                         // 接收客户端的基本用户信息
 751                         String inf = r.readLine();
 752                         StringTokenizer st = new StringTokenizer(inf, "#");
 753                         User user = new User(st.nextToken(), st.nextToken());
 754                         // 反馈连接成功信息
 755                         w.println("MAX#服务器:对不起," + user.getName()
 756                                 + user.getIp() + ",服务器在线人数已达上限,请稍后尝试连接!");
 757                         w.flush();
 758                         // 释放资源
 759                         r.close();
 760                         w.close();
 761                         socket.close();
 762                         continue;
 763                     }
 764                     ClientThread client = new ClientThread(socket);
 765                     client.start();// 开启对此客户端服务的线程
 766                     client.getUser().setState(1);//在线状态
 767                     clients.add(client);
 768                     listModel.addElement(client.getUser().getName());// 更新在线列表
 769                     contentArea.append(client.getUser().getName()
 770                             + client.getUser().getIp() + "上线!\r\n");
 771 //                    user_name_update();
 772                 } catch (IOException e) {
 773                     e.printStackTrace();
 774                 }
 775             }
 776         }
 777     }
 778 
 779     /**
 780      * 为一个客户端服务的线程
 781      */
 782     class ClientThread extends Thread {
 783         private Socket socket;
 784         private BufferedReader reader;
 785         private PrintWriter writer;
 786         private User user;
 787 
 788         public BufferedReader getReader() {
 789             return reader;
 790         }
 791 
 792         public PrintWriter getWriter() {
 793             return writer;
 794         }
 795 
 796         public User getUser() {
 797             return user;
 798         }
 799 
 800         // 客户端线程的构造方法
 801         public ClientThread(Socket socket) {
 802             try {
 803                 this.socket = socket;
 804                 reader = new BufferedReader(new InputStreamReader(socket
 805                         .getInputStream()));
 806                 writer = new PrintWriter(socket.getOutputStream());
 807                 // 接收客户端的基本用户信息
 808                 String inf = reader.readLine();
 809                 StringTokenizer st = new StringTokenizer(inf, "#");
 810                 user = new User(st.nextToken(), st.nextToken());
 811                 // 反馈连接成功信息
 812                 writer.println(user.getName() + user.getIp() + "与服务器连接成功!");
 813                 writer.flush();
 814 
 815 
 816             } catch (IOException e) {
 817                 e.printStackTrace();
 818             }
 819         }
 820 
 821         @SuppressWarnings("deprecation")
 822         public void run() {// 不断接收客户端的消息,进行处理。
 823             String message = null;
 824             while (true) {
 825                 try {
 826                     message = reader.readLine();// 接收客户端消息
 827                     StringTokenizer stringTokenizer = new StringTokenizer(
 828                             message, "#");
 829                     String command = stringTokenizer.nextToken();// 命令
 830                     if (command.equals("CLOSE"))// 下线命令
 831                     {
 832                         contentArea.append(this.getUser().getName()
 833                                 + this.getUser().getIp() + "下线!\r\n");
 834                         // 断开连接释放资源
 835                         user_offLine(this.getUser().getName());
 836                         this.getUser().setState(0);
 837                         reader.close();
 838                         writer.close();
 839                         socket.close();
 840 
 841                         user_name_update();//更新用户状态
 842 
 843 
 844                         //反馈用户状态
 845                         String liststr = "";
 846                         for (int j = 1; j < all_listModel.size(); j++) {
 847                             liststr += all_listModel.get(j) + "#";
 848                         }
 849                         // 向所有在线用户发送该用户上线命令
 850                         for (int j = clients.size()-1 ; j >= 0; j--) {
 851                             clients.get(j).getWriter().println(
 852                                     "USERLIST#" + all_listModel.size() + "#" + liststr);
 853                             clients.get(j).getWriter().flush();
 854                         }
 855                         //user_name_update();//更新用户状态
 856 
 857                         listModel.removeElement(user.getName());// 更新在线列表
 858 
 859                         // 删除此条客户端服务线程
 860                         for (int i = clients.size() - 1; i >= 0; i--) {
 861                             if (clients.get(i).getUser() == user) {
 862                                 ClientThread temp = clients.get(i);
 863                                 clients.remove(i);// 删除此用户的服务线程
 864                                 temp.stop();// 停止这条服务线程
 865                                 return;
 866                             }
 867                         }
 868                     } else if (command.equals("USERLOGIN")) {
 869                         String username = stringTokenizer.nextToken();
 870                         String password = stringTokenizer.nextToken();
 871                         int serverPort = Integer.parseInt(stringTokenizer.nextToken());
 872                         String myIP = stringTokenizer.nextToken();
 873                         int i = user_login(username, password,serverPort,myIP);
 874                         if (1 == i) {
 875                             user_name_update();
 876                             String msg = get_message(username);
 877                             if (msg.equals("")) {
 878                                 writer.println("USERLOGIN#OK#");
 879                                 writer.flush();
 880                             } else {
 881                                 writer.println("USERLOGIN#OK#" + msg);
 882                                 writer.flush();
 883                             }
 884 
 885 
 886                             //反馈用户状态
 887                             String temp = "";
 888                             for (int j = 1; j < all_listModel.size(); j++) {
 889                                 temp += all_listModel.get(j) + "#";
 890                             }
 891                             // 向所有在线用户发送该用户上线命令
 892                             for (int j = clients.size()-1 ; j >= 0; j--) {
 893                                 clients.get(j).getWriter().println(
 894                                         "USERLIST#" + all_listModel.size() + "#" + temp);
 895                                 clients.get(j).getWriter().flush();
 896                             }
 897 
 898                         } else if (2 == i) {
 899                             writer.println("USERLOGIN#ALREADY");
 900                             writer.flush();
 901                         } else {
 902                             writer.println("USERLOGIN#NO");
 903                             writer.flush();
 904 
 905                         }
 906                         //user_name_update();
 907                     } else if (command.equals("USERZHUCE")) {
 908                         String username = stringTokenizer.nextToken();
 909                         String password = stringTokenizer.nextToken();
 910                         String youxiang = stringTokenizer.nextToken();
 911                         int i = user_register(username, password, youxiang);
 912                         if (1 == i) {
 913                             writer.println("USERZHUCE#OK");
 914                             writer.flush();
 915                             contentArea.append("有新用户注册!     用户名:" + username + "\r\n");
 916                             user_name_update();//更新用户状态
 917                         } else if (i == 2) {
 918                             writer.println("USERZHUCE#exict");
 919                             writer.flush();
 920                         } else {
 921                             writer.println("USERZHUCE#NO");
 922                             writer.flush();
 923                         }
 924                     } else if (command.equals("USERFORGET")) {
 925                         String username = stringTokenizer.nextToken();
 926                         String youxiang = stringTokenizer.nextToken();
 927                         String new_password = stringTokenizer.nextToken();
 928                         int i = user_forget(username, youxiang, new_password);
 929                         if (1 == i) {
 930                             //JOptionPane.showMessageDialog(frame, "登陆成功!" );
 931                             writer.println("USERFORGET#OK");
 932                             writer.flush();
 933                             contentArea.append("   用户:" + username + "  修改密码!\r\n");
 934                         } else if (i == 2) {
 935                             writer.println("USERFORGET#YOUXIANG_WRONG");
 936                             writer.flush();
 937                         } else if (i == 3) {
 938                             writer.println("USERFORGET#NAME_NO_exict");
 939                             writer.flush();
 940                         } else {
 941                             writer.println("USERFORGET#NO");
 942                             writer.flush();
 943                         }
 944                     } else if (command.equals("P2P")) {
 945                         String username = stringTokenizer.nextToken();
 946                         int i = get_user_serverPort(username);
 947                         String ip = get_user_serverIP(username);
 948                         if(i!=0){
 949                             writer.println("P2P#OK#"+username+"#"+i+"#"+ip);
 950                             writer.flush();
 951                         }else{
 952                             writer.println("P2P#NO#"+username);
 953                             writer.flush();
 954                         }
 955                     }else if(command.equals("LIXIAN")){
 956                         String username_sent = stringTokenizer.nextToken();
 957                         String username_receive = stringTokenizer.nextToken();
 958                         String msg = stringTokenizer.nextToken();
 959                         send_messageTo_board(username_sent,username_receive,msg);
 960                         System.out.println("离线发送ok");
 961                     } else {
 962                         dispatcherMessage(message);// 转发消息
 963                     }
 964                 } catch (IOException e) {
 965                     e.printStackTrace();
 966                 }
 967             }
 968         }
 969 
 970         public int get_user_serverPort(String user_name){
 971             try {
 972                 Connection con = null; //定义一个MYSQL链接对象
 973                 Class.forName("com.mysql.jdbc.Driver").newInstance();//MYSQL驱动
 974                 con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/server_db", "root", "root"); //链接本地MYSQL
 975                 Statement stmt; //创建声明
 976                 stmt = con.createStatement();
 977 
 978                 //查询数据,不能有相同的用户名
 979                 String selectSql = "SELECT * FROM user";
 980                 ResultSet selectRes = stmt.executeQuery(selectSql);
 981                 while (selectRes.next()) { //循环输出结果集
 982                     String username_db = selectRes.getString("username");
 983                     if (user_name.equals(username_db)) {
 984                         int serverPort = selectRes.getInt("serverPort");
 985                         return serverPort;
 986                     }
 987                 }
 988             } catch (Exception e) {
 989                 System.out.print("MYSQL ERROR:" + e.getMessage());
 990             }
 991             return 0;
 992         }
 993 
 994         public String get_user_serverIP(String user_name){
 995             try {
 996                 Connection con = null; //定义一个MYSQL链接对象
 997                 Class.forName("com.mysql.jdbc.Driver").newInstance();//MYSQL驱动
 998                 con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/server_db", "root", "root"); //链接本地MYSQL
 999                 Statement stmt; //创建声明
1000                 stmt = con.createStatement();
1001 
1002                 //查询数据,不能有相同的用户名
1003                 String selectSql = "SELECT * FROM user";
1004                 ResultSet selectRes = stmt.executeQuery(selectSql);
1005                 while (selectRes.next()) { //循环输出结果集
1006                     String username_db = selectRes.getString("username");
1007                     if (user_name.equals(username_db)) {
1008                         String serverIP = selectRes.getString("ipAdres");
1009                         return serverIP;
1010                     }
1011                 }
1012             } catch (Exception e) {
1013                 System.out.print("MYSQL ERROR:" + e.getMessage());
1014             }
1015             return "";
1016         }
1017 
1018         public String get_message(String name) {
1019             try {
1020                 Connection con = null; //定义一个MYSQL链接对象
1021                 Class.forName("com.mysql.jdbc.Driver").newInstance();//MYSQL驱动
1022                 con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/server_db", "root", "root"); //链接本地MYSQL
1023                 Statement stmt; //创建声明
1024                 stmt = con.createStatement();
1025 
1026                 //查询数据,不能有相同的用户名
1027                 String selectSql = "SELECT * FROM user";
1028                 ResultSet selectRes = stmt.executeQuery(selectSql);
1029                 while (selectRes.next()) { //循环输出结果集
1030                     int Id = selectRes.getInt("Id");
1031                     String username_db = selectRes.getString("username");
1032                     if (name.equals(username_db)) {
1033                         String message = selectRes.getString("message");
1034                         String updateSql = "UPDATE user SET message = \'\' WHERE Id = " + Id + "";
1035                         stmt.executeUpdate(updateSql);
1036                         return message;
1037                     }
1038                 }
1039                 return "";
1040             } catch (Exception e) {
1041                 System.out.print("MYSQL ERROR:" + e.getMessage());
1042             }
1043             return "";
1044         }
1045 
1046         // 转发消息
1047         public void dispatcherMessage(String message) {
1048             StringTokenizer stringTokenizer = new StringTokenizer(message, "#");
1049             String source = stringTokenizer.nextToken();
1050             String owner = stringTokenizer.nextToken();
1051             String content = stringTokenizer.nextToken();
1052 
1053             if (owner.equals("ALL")) {// 群发
1054                 message = source + "说:" + content;
1055                 contentArea.append(message + "\r\n");
1056                 for (int i = clients.size() - 1; i >= 0; i--) {
1057                     clients.get(i).getWriter().println(message + "(多人发送)");
1058                     clients.get(i).getWriter().flush();
1059                 }
1060             } else {
1061                 for (int i = clients.size() - 1; i >= 0; i--) {
1062                     if (clients.get(i).user.getName().equals(owner)) {
1063                         clients.get(i).getWriter().println(owner + "  对你说: " + content);
1064                         clients.get(i).getWriter().flush();
1065                         //contentArea.append(owner+"  对    "+ clients.get(i).user.getName()+ "  说  :"+ content+"\r\n");
1066                     }
1067                     if (clients.get(i).user.getName().equals(source)) {
1068                         clients.get(i).getWriter().println("对   " + source + "  说: " + content);
1069                         clients.get(i).getWriter().flush();
1070                     }
1071                 }
1072             }
1073         }
1074     }
1075 }

  1 import java.io.BufferedOutputStream;
  2 import java.io.BufferedReader;
  3 import java.io.DataOutputStream;
  4 import java.io.File;
  5 import java.io.FileInputStream;
  6 import java.io.FileNotFoundException;
  7 import java.io.IOException;
  8 import java.io.InputStreamReader;
  9 import java.io.PrintWriter;
 10 import java.net.ServerSocket;
 11 import java.net.Socket;
 12 
 13 import javax.swing.JFileChooser;
 14 import javax.swing.JFrame;
 15 import javax.swing.JOptionPane;
 16 import javax.swing.ProgressMonitor;
 17 import javax.swing.ProgressMonitorInputStream;
 18 
 19 
 20 public class SendFileThread extends Thread {
 21     private Socket clientSocket;
 22     private String name;
 23     JFileChooser sourceFileChooser;
 24     int status;
 25     JFrame JFrame;
 26 
 27     public SendFileThread(JFrame frame, Socket socket, String name, JFileChooser sourceFileChooser, int status) {
 28         this.clientSocket = socket;
 29         this.name = name;
 30         this.sourceFileChooser = sourceFileChooser;
 31         this.status = status;
 32         this.JFrame = frame;
 33     }
 34 
 35     public void run() {
 36 //        JFileChooser sourceFileChooser = new JFileChooser(".");
 37 //        sourceFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
 38 //        int status = sourceFileChooser.showOpenDialog(null);
 39         if (status == JFileChooser.APPROVE_OPTION) {
 40             File sourceFile = new File(sourceFileChooser.getSelectedFile().getPath());
 41             String sourceFilePath = sourceFile.getAbsolutePath();
 42             String fileName = sourceFile.getName();
 43             //System.out.println(sourceFilePath+"\\"+fileName);
 44             try {
 45                 PrintWriter sendToClient = new PrintWriter(clientSocket.getOutputStream());
 46                 BufferedReader getFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
 47                 ServerSocket fileSenderSocket = null;
 48                 try {
 49                     fileSenderSocket = new ServerSocket(0);
 50                 } catch (IOException ex1) {
 51                     JOptionPane.showMessageDialog(JFrame, "无法分配端口以发送此文件!", "错误", JOptionPane.ERROR_MESSAGE);
 52                 }
 53                 sendToClient.println("FILE#" + fileSenderSocket.getLocalPort() + "#" + fileName + "#"
 54                         + String.valueOf(sourceFile.length()) + "#" + clientSocket.getInetAddress().getHostAddress() + "#" + name);
 55                 sendToClient.flush();
 56                 //System.out.println("Sender: "+fileSenderSocket.getLocalSocketAddress());
 57                 Socket fileReceiverSocket = fileSenderSocket.accept();
 58 
 59                 BufferedReader getFromReceiver = null;
 60                 PrintWriter sendToReceiver = null;
 61                 try {
 62                     getFromReceiver = new BufferedReader(new InputStreamReader(fileReceiverSocket.getInputStream()));
 63                     sendToReceiver = new PrintWriter(fileReceiverSocket.getOutputStream());
 64                 } catch (IOException ex) {
 65                 } finally {
 66                 }
 67                 String judge = getFromReceiver.readLine();
 68                 if (judge.equals("accepted")) {
 69                     DataOutputStream sendFileToReceiver = new DataOutputStream(new BufferedOutputStream(fileReceiverSocket.getOutputStream()));
 70                     ProgressMonitorInputStream monitor;
 71                     FileInputStream sendFileStream = null;
 72                     try {
 73                         sendFileStream = new FileInputStream(sourceFile);
 74                     } catch (FileNotFoundException ex) {
 75                         sendToReceiver.flush();
 76                         sendFileToReceiver.writeByte(0);
 77                         sendFileToReceiver.flush();
 78                         return;
 79                     }
 80                     monitor = new ProgressMonitorInputStream(JFrame, "正在发送: " + fileName, sendFileStream);
 81                     ProgressMonitor progressMonitor = monitor.getProgressMonitor();
 82 
 83                     int read_unit = 500;
 84                     long fileSize = monitor.available();
 85                     int readed = 0;
 86                     byte[] data = new byte[read_unit];
 87                     try {
 88                         sendFileToReceiver.writeByte(1);
 89                         sendFileToReceiver.flush();
 90                         while (monitor.available() > 0) {
 91                             int in = monitor.read(data);
 92                             readed += in;
 93                             float process = (float) readed / fileSize * 100;
 94                             progressMonitor.setNote(process + " % 完成");
 95                             if (in > 0) {
 96                                 sendFileToReceiver.write(data, 0, in);
 97                             }
 98                         }
 99                         sendFileToReceiver.flush();
100                     } catch (IOException e) {
101                         JOptionPane.showMessageDialog(JFrame, "传输中断!", "错误", JOptionPane.ERROR_MESSAGE);
102                     } finally {
103                         if (sendFileStream != null)
104                             try {
105                                 sendFileStream.close();
106                                 monitor.close();
107                             } catch (IOException e) {
108                             }
109                     }
110                     try {
111                         fileReceiverSocket.close();
112                     } catch (IOException ex1) {
113                     }
114                 } else if (judge.equals("refused")) {
115                     JOptionPane.showMessageDialog(JFrame, "对方拒绝接受文件 " + fileName, "错误!", JOptionPane.INFORMATION_MESSAGE);
116                 }
117 
118             } catch (IOException ex) {
119             } finally {
120             }
121         }
122     }
123 }
View Code
 1 //用户信息类
 2 public class User{
 3     private String name;
 4     private String ip;
 5     private int state;
 6 
 7     public User(String name, String ip) {
 8         this.name = name;
 9         this.ip = ip;
10         state = 0;
11     }
12 
13     public String getName() {
14         return name;
15     }
16 
17     public void setName(String name) {
18         this.name = name;
19     }
20 
21     public String getIp() {
22         return ip;
23     }
24 
25     public void setIp(String ip) {
26         this.ip = ip;
27     }
28 
29     public int getState() {
30         return state;
31     }
32 
33     public void setState(int state) {
34         this.state = state;
35     }
36 }
View Code

 

数据库:

是通过MD5加密保存。

 

客户端代码:

   1 package com.company;
   2 
   3 import java.awt.BorderLayout;
   4 import java.awt.Color;
   5 import java.awt.Font;
   6 import java.awt.GridLayout;
   7 import java.awt.Toolkit;
   8 import java.awt.event.ActionEvent;
   9 import java.awt.event.ActionListener;
  10 import java.awt.event.WindowAdapter;
  11 import java.awt.event.WindowEvent;
  12 import java.io.*;
  13 import java.net.BindException;
  14 import java.net.InetAddress;
  15 import java.net.ServerSocket;
  16 import java.net.Socket;
  17 import java.sql.Connection;
  18 import java.sql.DriverManager;
  19 import java.sql.ResultSet;
  20 import java.sql.Statement;
  21 import java.util.ArrayList;
  22 import java.util.HashMap;
  23 import java.util.Map;
  24 import java.util.StringTokenizer;
  25 
  26 import javax.swing.*;
  27 import javax.swing.border.TitledBorder;
  28 import javax.swing.event.ListSelectionEvent;
  29 import javax.swing.event.ListSelectionListener;
  30 
  31 //import socket_chat_server.Server.ClientThread;
  32 //import socket_chat_server.Server.SelecTry;
  33 
  34 public class Client{
  35 
  36     private JPanel sendPanel;
  37     private JButton btn_send_file;
  38     private JFrame frame;
  39     private JList userList;
  40     private JTextArea textArea;
  41     private JTextField textField;
  42     private JTextField txt_port;
  43     private JTextField txt_hostIp;
  44     private JTextField txt_name;
  45     private JButton btn_start;
  46     private JButton btn_stop;
  47     private JButton btn_send;
  48     private JPanel northPanel;
  49     private JPanel southPanel;
  50     private JScrollPane rightScroll;
  51     private JScrollPane leftScroll;
  52     private JSplitPane centerSplit;
  53 
  54     private JPanel logPanle;
  55     private JFrame loginframe;
  56     private JLabel label_username;
  57     private JLabel label_password;
  58     private JTextField txt_login_name;
  59     private JTextField txt_password;
  60     private JTextField txt_login_ip;
  61     private JTextField txt_login_port;
  62     private JTextField txt_login_forget;
  63     private JButton btn_submit;
  64     private JButton btn_zhuce;
  65     private JButton btn_forget_pass;
  66 
  67     private DefaultListModel listModel;
  68     private boolean isConnected = false;
  69 
  70     private int sendfor_who;
  71     private int server_port=0;
  72 
  73     private ServerSocket serverSocket;
  74     private ServerThread serverThread;
  75     private Socket socketfor_p2p;
  76     private boolean isConnected_p2p = false;
  77     private ArrayList<ClientThread> clients;//客户线程数组
  78     private PrintWriter P2P_printWriter;//点对点服务的输出流
  79     private BufferedReader P2P_bufferReader;//点对点服务的输入流
  80     private MessageThread_P2P messageThread_for_p2p;// 负责接收p2p消息的线程
  81     private Map<String, Boolean> P2P_connected_user = new HashMap<String, Boolean>();
  82 
  83     private Socket socket;
  84     private PrintWriter writer;
  85     private BufferedReader reader;
  86     private MessageThread messageThread;// 负责接收消息的线程
  87     private Map<String, User> onLineUsers = new HashMap<String, User>();// 所有在线用户
  88     private String myIP = "";//每一个客户端都有唯一的IP地址
  89 
  90     // 主方法,程序入口
  91     public static void main(String[] args) throws BindException {
  92         new Client();
  93 
  94     }
  95 
  96     class SelecTry implements ListSelectionListener
  97     {
  98         int change=0,who;
  99         public void valueChanged(ListSelectionEvent e){
 100             //System.out.println("you selected:"+listModel.getElementAt(userList.getSelectedIndex()));
 101             sendfor_who=userList.getSelectedIndex();
 102             isConnected_p2p = false;
 103         }
 104 
 105     }
 106 
 107     /**
 108      * 连接服务器
 109      *
 110      * @param port
 111      * @param hostIp
 112      * @param name
 113      */
 114     public boolean connectServer_p2p(int port, String hostIp, String name) {
 115         // 连接服务器
 116         try {
 117             socketfor_p2p = new Socket(hostIp, port);// 根据端口号和服务器ip建立连接
 118             P2P_printWriter = new PrintWriter(socketfor_p2p.getOutputStream());
 119             P2P_bufferReader = new BufferedReader(new InputStreamReader(socketfor_p2p
 120                     .getInputStream()));
 121 
 122             messageThread_for_p2p = new MessageThread_P2P(P2P_bufferReader);
 123             messageThread_for_p2p.start();
 124             P2P_connected_user.put(name,true);
 125             isConnected_p2p = true;// 已经连接上了
 126             return true;
 127         } catch (Exception e) {
 128             textArea.append("与端口号为:" + port + "    IP地址为:" + hostIp
 129                     + "   的服务连接失败!" + "\r\n");
 130             isConnected_p2p = false;// 未连接上
 131             return false;
 132         }
 133     }
 134 
 135     /**
 136      * 关闭服务
 137      */
 138     @SuppressWarnings("deprecation")
 139     public void closeServer() {
 140         try {
 141             if (serverThread != null)
 142                 serverThread.stop();// 停止服务器线程
 143 
 144             for (int i = clients.size() - 1; i >= 0; i--) {
 145                 // 给所有在线用户发送关闭命令
 146                 clients.get(i).getWriter().println("CLOSE#"+frame.getTitle());
 147                 clients.get(i).getWriter().flush();
 148                 // 释放资源
 149                 clients.get(i).stop();// 停止此条为客户端服务的线程
 150                 clients.get(i).reader_ptp.close();
 151                 clients.get(i).writer_ptp.close();
 152                 clients.get(i).socket.close();
 153                 clients.remove(i);
 154             }
 155             if (serverSocket != null) {
 156                 serverSocket.close();// 关闭服务器端连接
 157             }
 158             listModel.removeAllElements();// 清空用户列表
 159 //            isStart = false;
 160         } catch (IOException e) {
 161             e.printStackTrace();
 162 //            isStart = true;
 163         }
 164     }
 165 
 166     // 不断接收消息的线程
 167     class MessageThread_P2P extends Thread {
 168         private BufferedReader reader_ptp;
 169 
 170         // 接收消息线程的构造方法
 171         public MessageThread_P2P(BufferedReader reader) {
 172             this.reader_ptp = reader;
 173 
 174         }
 175 
 176         // 被动的关闭连接
 177         public synchronized void closeCon() throws Exception {
 178             System.out.println("close :*************");
 179             // 被动的关闭连接释放资源
 180             if (reader_ptp != null) {
 181                 reader_ptp.close();
 182             }
 183             if (P2P_printWriter != null) {
 184                 P2P_printWriter.close();
 185             }
 186             if (socketfor_p2p != null) {
 187                 socketfor_p2p.close();
 188             }
 189             isConnected_p2p = false;// 修改状态为断开
 190 
 191         }
 192 
 193         public void run() {
 194             String message = "";
 195             while (true) {
 196                 try {
 197                     message = reader_ptp.readLine();
 198                     StringTokenizer stringTokenizer = new StringTokenizer(
 199                             message, "/#");
 200                     String command = stringTokenizer.nextToken();// 命令
 201                     if (command.equals("CLOSE"))// 服务器已关闭命令
 202                     {
 203                         String user = stringTokenizer.nextToken();
 204                         textArea.append("用户 "+user+"  已下线,p2p服务已关闭!\r\n");
 205                         closeCon();// 被动的关闭连接
 206                         JOptionPane.showMessageDialog(frame, "用户 "+user+"  已下线,p2p服务已关闭!", "错误",
 207                                 JOptionPane.ERROR_MESSAGE);
 208                         return;// 结束线程
 209                     } else if (command.equals("FILE")) {
 210                         int portNumber = Integer.parseInt(stringTokenizer.nextToken());
 211                         String fileName = stringTokenizer.nextToken();
 212                         long fileSize = Long.parseLong(stringTokenizer.nextToken());
 213                         String ip = stringTokenizer.nextToken();
 214                         String Nickname = stringTokenizer.nextToken();
 215                         ReceiveFileThread receiveFile = new ReceiveFileThread(textArea,frame,ip, portNumber, fileName, fileSize, Nickname);
 216                         receiveFile.start();
 217                         textArea.append("从 "+Nickname+" 接受文件:"+fileName+",大小为:"+fileSize
 218                                 +"ip:"+ip+"port:"+portNumber+"\r\n");
 219                     } else {// 普通消息
 220                         textArea.append(""+message + "\r\n");
 221                     }
 222                 } catch (IOException e) {
 223                     e.printStackTrace();
 224                 } catch (Exception e) {
 225                     e.printStackTrace();
 226                 }
 227             }
 228         }
 229     }
 230 
 231     /**
 232      * 启动服务器
 233      *
 234      * @param port
 235      * @throws java.net.BindException
 236      */
 237     public void serverStart(int port) throws java.net.BindException {
 238         try {
 239             clients = new ArrayList<ClientThread>();
 240             serverSocket = new ServerSocket(port);
 241             serverThread = new ServerThread(serverSocket);
 242             serverThread.start();
 243             server_port = serverSocket.getLocalPort();
 244             InetAddress addr = InetAddress.getLocalHost();
 245             myIP = addr.getHostAddress();//获得本机IP
 246 //            myIP = serverSocket.getInetAddress().getHostAddress();
 247             System.out.println("mmyIP=="+myIP+"\r\n");
 248         } catch (BindException e) {
 249             throw new BindException("端口号已被占用,请换一个!");
 250         } catch (Exception e1) {
 251             e1.printStackTrace();
 252             throw new BindException("启动服务器异常!");
 253         }
 254     }
 255 
 256     /**
 257      * 为另一个主动链接的客户端提供服务的线程
 258      */
 259     class ClientThread extends Thread {
 260         private Socket socket;
 261         private BufferedReader reader_ptp;
 262         private PrintWriter writer_ptp;
 263         private User user;
 264 
 265         public BufferedReader getReader() {
 266             return reader_ptp;
 267         }
 268 
 269         public PrintWriter getWriter() {
 270             return writer_ptp;
 271         }
 272 
 273         public User getUser() {
 274             return user;
 275         }
 276 
 277         // 客户端线程的构造方法
 278         public ClientThread(Socket socket) {
 279             try {
 280                 this.socket = socket;
 281                 reader_ptp = new BufferedReader(new InputStreamReader(socket
 282                         .getInputStream()));
 283                 writer_ptp = new PrintWriter(socket.getOutputStream());
 284 
 285                 // 接收客户端的基本用户信息
 286                 String inf = reader_ptp.readLine();
 287                 StringTokenizer st = new StringTokenizer(inf, "#");
 288                 user = new User(st.nextToken(), socket.getLocalAddress().toString());
 289                 // 反馈连接成功信息
 290                 writer_ptp.println(frame.getTitle()+"  对你说:  "+user.getName()+"/"+user.getIp()+"你好!"+"与我"+frame.getTitle()+"建立链接成功!");
 291                 writer_ptp.flush();
 292 //                // 反馈当前在线用户信息
 293 //                if (clients.size() > 0) {
 294 //                    String temp = "";
 295 //                    for (int i = clients.size() - 1; i >= 0; i--) {
 296 //                        temp += (clients.get(i).getUser().getName() + "/" + clients
 297 //                                .get(i).getUser().getIp())
 298 //                                + "#";
 299 //                    }
 300 //                    writer.println("USERLIST#" + clients.size() + "#" + temp);
 301 //                    writer.flush();
 302 //                }
 303 //                // 向所有在线用户发送该用户上线命令
 304 //                for (int i = clients.size() - 1; i >= 0; i--) {
 305 //                    clients.get(i).getWriter().println(
 306 //                            "ADD#" + user.getName() + user.getIp());
 307 //                    clients.get(i).getWriter().flush();
 308 //                }
 309             } catch (IOException e) {
 310                 e.printStackTrace();
 311             }
 312         }
 313 
 314         @SuppressWarnings("deprecation")
 315         public void run() {// 不断接收客户端的消息,进行处理。
 316             String message = null;
 317             while (true) {
 318                 try {
 319                     message = reader_ptp.readLine();// 接收客户端消息
 320                     StringTokenizer stringTokenizer = new StringTokenizer(message,"/#");
 321                     String command = stringTokenizer.nextToken();
 322                     if (command.equals("CLOSE"))// 下线命令
 323                     {
 324                         textArea.append("与"+this.getUser().getName()
 325                                 + this.getUser().getIp() + "建立连接成功!\r\n");
 326                         // 断开连接释放资源
 327                         this.getUser().setState(0);
 328                         reader.close();
 329                         writer.close();
 330                         socket.close();
 331 
 332                     } else if (command.equals("FILE")) {
 333                         int portNumber = Integer.parseInt(stringTokenizer.nextToken());
 334                         String fileName = stringTokenizer.nextToken();
 335                         long fileSize = Long.parseLong(stringTokenizer.nextToken());
 336                         String ip = stringTokenizer.nextToken();
 337                         String Nickname = stringTokenizer.nextToken();
 338                         ReceiveFileThread receiveFile = new ReceiveFileThread(textArea,frame,ip, portNumber, fileName, fileSize, Nickname);
 339                         receiveFile.start();
 340                         textArea.append("从 "+Nickname+" 接受文件 :"+fileName+",大小为:  "+fileSize
 341                                 +"   ip: "+ip+"    port:"+portNumber+"\r\n");
 342                     }else {
 343                         textArea.append(user.getName()+"  对你说: "+message+"\r\n");
 344                     }
 345                 } catch (IOException e) {
 346                     e.printStackTrace();
 347                 }
 348             }
 349         }
 350 
 351     }
 352 
 353     /**
 354      * 服务线程
 355      */
 356     class ServerThread extends Thread {
 357         private ServerSocket serverSocket;
 358 
 359         // 服务器线程的构造方法
 360         public ServerThread(ServerSocket serverSocket) {
 361             this.serverSocket = serverSocket;
 362         }
 363 
 364         public void run() {
 365             while (true) {// 不停的等待客户端的链接
 366                 try {
 367                     Socket socket = serverSocket.accept();
 368                     ClientThread client = new ClientThread(socket);
 369                     client.start();// 开启对此客户端服务的线程
 370                     clients.add(client);
 371                     textArea.append("有新用户p2p链接\r\n");
 372 //                    user_name_update();
 373                 } catch (IOException e) {
 374                     e.printStackTrace();
 375                 }
 376             }
 377         }
 378     }
 379 
 380 
 381     public void sendFile() {
 382         //文件选择对话框启动,当选择了文件以后给每一个client发送文件
 383         JFileChooser sourceFileChooser = new JFileChooser(".");
 384         sourceFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
 385         int status = sourceFileChooser.showOpenDialog(frame);
 386         File sourceFile = new File(sourceFileChooser.getSelectedFile().getPath());
 387         //服务器text area提示
 388         textArea.append("发送文件:" + sourceFile.getName() + "\r\n");
 389 
 390         if(sendfor_who==0){
 391             textArea.append("对服务器发送文件!");
 392         }else{
 393             StringTokenizer st = new StringTokenizer(listModel.getElementAt(sendfor_who)+"", "---()");
 394             String user_name = st.nextToken();
 395             String user_state = st.nextToken();
 396             if (user_state.equals("在线")) {
 397                 for (int i = clients.size()-1; i >= 0; i--) {
 398                     if (clients.get(i).getUser().getName().equals(user_name)) {
 399                         SendFileThread sendFile = new SendFileThread(frame, clients.get(i).socket, frame.getTitle(), sourceFileChooser, status);
 400                         sendFile.start();
 401                         //client端提示
 402                         textArea.append("给  "+user_name+"  发送一个文件:" + sourceFile.getName() + "\r\n");
 403                         return;
 404                     }
 405                 }
 406                 SendFileThread sendFile = new SendFileThread(frame, socketfor_p2p, frame.getTitle(), sourceFileChooser, status);
 407                 sendFile.start();
 408                 //client端提示
 409                 textArea.append("给  "+user_name+"  发送一个文件:" + sourceFile.getName() + "\r\n");
 410             }else{
 411                 JOptionPane.showMessageDialog(frame, "用户不在线,不能发送文件!");
 412             }
 413         }
 414 
 415     }
 416 
 417 
 418 
 419     // 执行发送
 420     public void send() {
 421         if (!isConnected) {
 422             JOptionPane.showMessageDialog(frame, "还没有连接服务器,无法发送消息!", "错误",
 423                     JOptionPane.ERROR_MESSAGE);
 424             return;
 425         }
 426         String message = textField.getText().trim();
 427         if (message == null || message.equals("")) {
 428             JOptionPane.showMessageDialog(frame, "消息不能为空!", "错误",
 429                     JOptionPane.ERROR_MESSAGE);
 430             return;
 431         }
 432         //sendMessage(frame.getTitle() + "#" + "ALL" + "#" + message);
 433         if(sendfor_who==0){
 434             sendMessage(frame.getTitle() + "#" + "ALL" + "#" + message);
 435             textField.setText(null);
 436         }else{
 437             StringTokenizer st = new StringTokenizer(listModel.getElementAt(sendfor_who)+"", "---()");
 438             String user_name = st.nextToken();
 439             String user_state = st.nextToken();
 440             if (user_state.equals("在线")) {
 441                 for (int i = clients.size()-1; i >= 0; i--) {
 442                     if (clients.get(i).getUser().getName().equals(user_name)) {
 443                         clients.get(i).writer_ptp.println("对 "+user_name+"  说:  "+message+"\r\n");
 444                         clients.get(i).writer_ptp.flush();
 445                         textArea.append("对  "+user_name+"  说: "+message+"\r\n");
 446                         textField.setText(null);
 447                         return;
 448                     }
 449                 }
 450                 if (!isConnected_p2p) {
 451                     JOptionPane.showMessageDialog(frame, "点对点即将连接!");
 452                     sendMessage("P2P#"+user_name);
 453                 }else{
 454                     P2P_printWriter.println(message);
 455                     P2P_printWriter.flush();
 456                     textArea.append("对  "+user_name+"  说: "+message+"\r\n");
 457                     textField.setText(null);
 458                 }
 459 
 460             }else{
 461                 JOptionPane.showMessageDialog(frame, "用户不在线,已存为留言!");
 462                 sendMessage("LIXIAN#"+frame.getTitle() + "#" + user_name + "#" + message);
 463                 textArea.append("对  "+user_name+"  留言: "+message+"\r\n");
 464                 textField.setText(null);
 465             }
 466         }
 467     }
 468 
 469     public void Login(){
 470         Font font = new Font("宋体", 1, 16);
 471 
 472         logPanle = new JPanel();
 473         //logPanle.setLayout(new GridLayout(2, 2));
 474         logPanle.setBounds(2, 45, 250, 225);
 475         logPanle.setBackground(Color.lightGray);
 476         logPanle.setLayout(new GridLayout(5, 2, 20, 20));
 477 
 478         label_username = new JLabel("用户名:");
 479         label_username.setFont(font);
 480         label_username.setHorizontalAlignment(SwingConstants.CENTER);
 481         logPanle.add(label_username);
 482 
 483         txt_login_name = new JTextField("name");
 484         txt_login_name.setFont(font);
 485         logPanle.add(txt_login_name);
 486 
 487         label_password = new JLabel("密 码:");
 488         label_password.setFont(font);
 489         label_password.setHorizontalAlignment(SwingConstants.CENTER);
 490         logPanle.add(label_password);
 491 
 492         txt_password = new JTextField("");
 493         txt_password.setFont(font);
 494         logPanle.add(txt_password);
 495 
 496         txt_login_ip = new JTextField("127.0.0.1");
 497         txt_login_ip.setFont(font);
 498         logPanle.add(txt_login_ip);
 499 
 500         txt_login_port = new JTextField("6666");
 501         txt_login_port.setFont(font);
 502         logPanle.add(txt_login_port);
 503 
 504         logPanle.add(txt_login_ip);
 505         logPanle.add(txt_login_port);
 506 
 507         btn_submit = new JButton("登陆");
 508         btn_submit.setFont(font);
 509         btn_submit.addActionListener(new ActionListener() {
 510             public void actionPerformed(ActionEvent e) {
 511                 int port;
 512                 String message_name = txt_login_name.getText().trim();
 513                 if (message_name == null || message_name.equals("")) {
 514                     JOptionPane.showMessageDialog(logPanle, "用户名不能为空!", "错误",
 515                             JOptionPane.ERROR_MESSAGE);
 516                     return;
 517                 }
 518                 String message_pw = txt_password.getText().trim();
 519                 if (message_pw == null || message_pw.equals("")) {
 520                     JOptionPane.showMessageDialog(logPanle, "密码不能为空!", "错误",
 521                             JOptionPane.ERROR_MESSAGE);
 522                     return;
 523                 }
 524                 if (isConnected) {
 525                     String message1 = txt_login_name.getText().trim();
 526                     if (message1 == null || message1.equals("")) {
 527                         JOptionPane.showMessageDialog(logPanle, "用户名不能为空!", "错误",
 528                                 JOptionPane.ERROR_MESSAGE);
 529                         return;
 530                     }
 531                     String message2 = txt_password.getText().trim();
 532                     if (message2 == null || message2.equals("")) {
 533                         JOptionPane.showMessageDialog(logPanle, "密码不能为空!", "错误",
 534                                 JOptionPane.ERROR_MESSAGE);
 535                         return;
 536                     }
 537                     sendMessage("USERLOGIN#"+message1+"#"+message2+"#"+server_port+"#"+myIP);
 538                     return;
 539                 }else{
 540                     try {
 541                         try {
 542                             port = Integer.parseInt(txt_login_port.getText().trim());
 543                         } catch (NumberFormatException e2) {
 544                             throw new Exception("端口号不符合要求!端口为整数!");
 545                         }
 546                         String hostIp = txt_login_ip.getText().trim();
 547                         String name = txt_login_name.getText().trim();
 548                         if (name.equals("") || hostIp.equals("")) {
 549                             throw new Exception("姓名、服务器IP不能为空!");
 550                         }
 551                         boolean flag = connectServer(port, hostIp, name);
 552                         if (flag == false) {
 553                             throw new Exception("与服务器连接失败!");
 554                         }
 555                         frame.setTitle(name);
 556                         listModel.addElement("全部用户");
 557                     } catch (Exception exc) {
 558                         JOptionPane.showMessageDialog(loginframe, exc.getMessage(),
 559                                 "错误", JOptionPane.ERROR_MESSAGE);
 560                         return;
 561                     }
 562                 }
 563 
 564                 sendMessage("USERLOGIN#"+message_name+"#"+message_pw+"#"+server_port+"#"+myIP);
 565             }
 566         });
 567         logPanle.add(btn_submit);
 568 
 569         btn_zhuce = new JButton("注册");
 570         btn_zhuce.setFont(font);
 571         btn_zhuce.addActionListener(new ActionListener() {
 572             public void actionPerformed(ActionEvent e) {
 573                 int port;
 574                 String message_name = txt_login_name.getText().trim();
 575                 if (message_name == null || message_name.equals("")) {
 576                     JOptionPane.showMessageDialog(logPanle, "用户名不能为空!", "错误",
 577                             JOptionPane.ERROR_MESSAGE);
 578                     return;
 579                 }
 580                 String message_pw = txt_password.getText().trim();
 581                 if (message_pw == null || message_pw.equals("")) {
 582                     JOptionPane.showMessageDialog(logPanle, "密码不能为空!", "错误",
 583                             JOptionPane.ERROR_MESSAGE);
 584                     return;
 585                 }
 586                 String message_yx = txt_login_forget.getText().trim();
 587                 if (message_yx == null || message_yx.equals("")) {
 588                     JOptionPane.showMessageDialog(logPanle, "注册邮箱不能为空!", "错误",
 589                             JOptionPane.ERROR_MESSAGE);
 590                     return;
 591                 }
 592 
 593                 if (isConnected) {
 594                     String message1 = txt_login_name.getText().trim();
 595                     if (message1 == null || message1.equals("")) {
 596                         JOptionPane.showMessageDialog(logPanle, "用户名不能为空!", "错误",
 597                                 JOptionPane.ERROR_MESSAGE);
 598                         return;
 599                     }
 600                     String message2 = txt_password.getText().trim();
 601                     if (message2 == null || message2.equals("")) {
 602                         JOptionPane.showMessageDialog(logPanle, "密码不能为空!", "错误",
 603                                 JOptionPane.ERROR_MESSAGE);
 604                         return;
 605                     }
 606                     String message3 = txt_login_forget.getText().trim();
 607                     if (message3 == null || message3.equals("")) {
 608                         JOptionPane.showMessageDialog(logPanle, "注册邮箱不能为空!", "错误",
 609                                 JOptionPane.ERROR_MESSAGE);
 610                         return;
 611                     }
 612                     sendMessage("USERZHUCE#"+message1+"#"+message2+"#"+message3);
 613                     return;
 614                 }else{
 615                     try {
 616                         try {
 617                             port = Integer.parseInt(txt_login_port.getText().trim());
 618                         } catch (NumberFormatException e2) {
 619                             throw new Exception("端口号不符合要求!端口为整数!");
 620                         }
 621                         String hostIp = txt_login_ip.getText().trim();
 622                         String name = txt_login_name.getText().trim();
 623                         if (name.equals("") || hostIp.equals("")) {
 624                             throw new Exception("姓名、服务器IP不能为空!");
 625                         }
 626                         boolean flag = connectServer(port, hostIp, name);
 627                         if (flag == false) {
 628                             throw new Exception("与服务器连接失败!");
 629                         }
 630                         frame.setTitle(name);
 631                         listModel.addElement("全部用户");
 632                     } catch (Exception exc) {
 633                         JOptionPane.showMessageDialog(frame, exc.getMessage(),
 634                                 "错误", JOptionPane.ERROR_MESSAGE);
 635                         return;
 636                     }
 637                 }
 638 
 639 
 640                 sendMessage("USERZHUCE#"+message_name+"#"+message_pw+"#"+message_yx);
 641             }
 642         });
 643         logPanle.add(btn_zhuce);
 644 
 645 
 646 
 647         txt_login_forget = new JTextField("");
 648         txt_login_forget.setFont(font);
 649         logPanle.add(txt_login_forget);
 650 
 651         btn_forget_pass = new JButton("密码找回");
 652         btn_forget_pass.setFont(font);
 653         btn_forget_pass.addActionListener(new ActionListener() {
 654             public void actionPerformed(ActionEvent e) {
 655                 int port;
 656 
 657                 String message_name = txt_login_name.getText().trim();
 658                 if (message_name == null || message_name.equals("")) {
 659                     JOptionPane.showMessageDialog(logPanle, "用户名不能为空!", "错误",
 660                             JOptionPane.ERROR_MESSAGE);
 661                     return;
 662                 }
 663                 String message_yx = txt_login_forget.getText().trim();
 664                 if (message_yx == null || message_yx.equals("")) {
 665                     JOptionPane.showMessageDialog(logPanle, "注册邮箱不能为空!", "错误",
 666                             JOptionPane.ERROR_MESSAGE);
 667                     return;
 668                 }
 669                 String message_pw = txt_password.getText().trim();
 670                 if (message_pw == null || message_pw.equals("")) {
 671                     JOptionPane.showMessageDialog(logPanle, "修改密码不能为空!", "错误",
 672                             JOptionPane.ERROR_MESSAGE);
 673                     return;
 674                 }
 675 
 676                 if (isConnected) {
 677                     String message1 = txt_login_name.getText().trim();
 678                     if (message1 == null || message1.equals("")) {
 679                         JOptionPane.showMessageDialog(logPanle, "用户名不能为空!", "错误",
 680                                 JOptionPane.ERROR_MESSAGE);
 681                         return;
 682                     }
 683                     String message2 = txt_login_forget.getText().trim();
 684                     if (message2 == null || message2.equals("")) {
 685                         JOptionPane.showMessageDialog(logPanle, "注册邮箱不能为空!", "错误",
 686                                 JOptionPane.ERROR_MESSAGE);
 687                         return;
 688                     }
 689                     String message3 = txt_password.getText().trim();
 690                     if (message3 == null || message3.equals("")) {
 691                         JOptionPane.showMessageDialog(logPanle, "修改密码不能为空!", "错误",
 692                                 JOptionPane.ERROR_MESSAGE);
 693                         return;
 694                     }
 695                     sendMessage("USERFORGET#"+message1+"#"+message2+"#"+message3);
 696                     return;
 697                 }else{
 698                     try {
 699                         try {
 700                             port = Integer.parseInt(txt_login_port.getText().trim());
 701                         } catch (NumberFormatException e2) {
 702                             throw new Exception("端口号不符合要求!端口为整数!");
 703                         }
 704                         String hostIp = txt_login_ip.getText().trim();
 705                         String name = txt_login_name.getText().trim();
 706                         if (name.equals("") || hostIp.equals("")) {
 707                             throw new Exception("姓名、服务器IP不能为空!");
 708                         }
 709                         boolean flag = connectServer(port, hostIp, name);
 710                         if (flag == false) {
 711                             throw new Exception("与服务器连接失败!");
 712                         }
 713                         frame.setTitle(name);
 714                         listModel.addElement("全部用户");
 715                     } catch (Exception exc) {
 716                         JOptionPane.showMessageDialog(frame, exc.getMessage(),
 717                                 "错误", JOptionPane.ERROR_MESSAGE);
 718                         return;
 719                     }
 720                 }
 721 
 722                 sendMessage("USERFORGET#"+message_name+"#"+message_yx+"#"+message_pw);
 723             }
 724         });
 725         logPanle.add(btn_forget_pass);
 726 
 727 
 728         logPanle.setBorder(new TitledBorder("登陆"));
 729         loginframe = new JFrame("登陆窗口");
 730         loginframe.add(logPanle,"Center");
 731         loginframe.setSize(300, 300);
 732         int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;
 733         int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;
 734         loginframe.setLocation((screen_width - loginframe.getWidth()) / 2,
 735                 (screen_height - loginframe.getHeight()) / 2);
 736         loginframe.setVisible(true);
 737 
 738         // 关闭窗口时事件
 739         loginframe.addWindowListener(new WindowAdapter() {
 740             public void windowClosing(WindowEvent e) {
 741                 if (isConnected) {
 742                     closeConnection();// 关闭连接
 743                     closeServer();//关闭服务程序
 744                 }
 745                 System.exit(0);// 退出程序
 746             }
 747         });
 748     }
 749 
 750     // 构造方法
 751     public Client() throws BindException {
 752 
 753         serverStart(0);
 754 
 755         SelecTry selectIndex=new SelecTry();
 756 
 757         textArea = new JTextArea();
 758         textArea.setEditable(false);
 759         textArea.setForeground(Color.blue);
 760         textField = new JTextField();
 761         txt_port = new JTextField("6666");
 762         txt_hostIp = new JTextField("127.0.0.1");
 763         txt_name = new JTextField("姓名");
 764         btn_start = new JButton("连接");
 765         btn_stop = new JButton("断开");
 766         btn_send = new JButton("发送");
 767         btn_send_file = new JButton("文件");
 768         listModel = new DefaultListModel();
 769         userList = new JList(listModel);
 770         //listModel.addElement("全部用户");
 771         userList.addListSelectionListener(selectIndex);
 772         northPanel = new JPanel();
 773         northPanel.setLayout(new GridLayout(1, 7));
 774         northPanel.add(new JLabel("     端口"));
 775         northPanel.add(txt_port);
 776         northPanel.add(new JLabel("    服务器IP"));
 777         northPanel.add(txt_hostIp);
 778         northPanel.add(new JLabel("     姓名"));
 779         northPanel.add(txt_name);
 780         northPanel.add(btn_start);
 781         northPanel.add(btn_stop);
 782         northPanel.setBorder(new TitledBorder("连接信息"));
 783 
 784         rightScroll = new JScrollPane(textArea);
 785         rightScroll.setBorder(new TitledBorder("消息显示区"));
 786         leftScroll = new JScrollPane(userList);
 787         leftScroll.setBorder(new TitledBorder("用户列表"));
 788         southPanel = new JPanel(new BorderLayout());
 789         sendPanel = new JPanel(new BorderLayout());
 790         southPanel.setBorder(new TitledBorder("写消息"));
 791         southPanel.add(textField, "Center");
 792         sendPanel.add(btn_send, BorderLayout.NORTH);
 793         sendPanel.add(btn_send_file, BorderLayout.SOUTH);
 794         southPanel.add(sendPanel, "East");
 795 
 796 
 797         centerSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftScroll,
 798                 rightScroll);
 799         centerSplit.setDividerLocation(150);
 800 
 801         frame = new JFrame("客户机");
 802         // 更改JFrame的图标:
 803         //frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Client.class.getResource("qq.png")));
 804         frame.setLayout(new BorderLayout());
 805         frame.add(northPanel, "North");
 806         frame.add(centerSplit, "Center");
 807         frame.add(southPanel, "South");
 808         frame.setSize(600, 400);
 809         int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;
 810         int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;
 811         frame.setLocation((screen_width - frame.getWidth()) / 2,
 812                 (screen_height - frame.getHeight()) / 2);
 813         frame.setVisible(false);
 814 
 815         // 写消息的文本框中按回车键时事件
 816         textField.addActionListener(new ActionListener() {
 817             public void actionPerformed(ActionEvent arg0) {
 818                 send();
 819             }
 820         });
 821 
 822         // 单击发送按钮时事件
 823         btn_send.addActionListener(new ActionListener() {
 824             public void actionPerformed(ActionEvent e) {
 825                 send();
 826             }
 827         });
 828 
 829         //单机文件按钮时事件
 830         btn_send_file.addActionListener(new ActionListener() {
 831             public void actionPerformed(ActionEvent arg0) {
 832                 sendFile();
 833             }
 834         });
 835 
 836         // 单击连接按钮时事件
 837 //        btn_start.addActionListener(new ActionListener() {
 838 //            public void actionPerformed(ActionEvent e) {
 839 //                int port;
 840 //                if (isConnected) {
 841 //                    JOptionPane.showMessageDialog(frame, "已处于连接上状态,不要重复连接!",
 842 //                            "错误", JOptionPane.ERROR_MESSAGE);
 843 //                    return;
 844 //                }
 845 //                try {
 846 //                    try {
 847 //                        port = Integer.parseInt(txt_port.getText().trim());
 848 //                    } catch (NumberFormatException e2) {
 849 //                        throw new Exception("端口号不符合要求!端口为整数!");
 850 //                    }
 851 //                    String hostIp = txt_hostIp.getText().trim();
 852 //                    String name = txt_name.getText().trim();
 853 //                    if (name.equals("") || hostIp.equals("")) {
 854 //                        throw new Exception("姓名、服务器IP不能为空!");
 855 //                    }
 856 //                    boolean flag = connectServer(port, hostIp, name);
 857 //                    if (flag == false) {
 858 //                        throw new Exception("与服务器连接失败!");
 859 //                    }
 860 //                    listModel.addElement("全部用户");
 861 //                    frame.setTitle(name);
 862 //                    JOptionPane.showMessageDialog(frame, "成功连接!");
 863 //                } catch (Exception exc) {
 864 //                    JOptionPane.showMessageDialog(frame, exc.getMessage(),
 865 //                            "错误", JOptionPane.ERROR_MESSAGE);
 866 //                }
 867 //            }
 868 //        });
 869 
 870         // 单击断开按钮时事件
 871         btn_stop.addActionListener(new ActionListener() {
 872             public void actionPerformed(ActionEvent e) {
 873                 if (!isConnected) {
 874                     JOptionPane.showMessageDialog(frame, "已处于断开状态,不要重复断开!",
 875                             "错误", JOptionPane.ERROR_MESSAGE);
 876                     return;
 877                 }
 878                 try {
 879                     boolean flag = closeConnection();// 断开连接
 880                     closeServer();
 881                     if (flag == false) {
 882                         throw new Exception("断开连接发生异常!");
 883                     }
 884                     JOptionPane.showMessageDialog(frame, "成功断开!");
 885                     frame.setVisible(false);
 886                     textArea.setText("");
 887                     loginframe.setVisible(true);
 888                     listModel.removeAllElements();
 889                 } catch (Exception exc) {
 890                     JOptionPane.showMessageDialog(frame, exc.getMessage(),
 891                             "错误", JOptionPane.ERROR_MESSAGE);
 892                 }
 893             }
 894         });
 895 
 896         // 关闭窗口时事件
 897         frame.addWindowListener(new WindowAdapter() {
 898             public void windowClosing(WindowEvent e) {
 899                 if (isConnected) {
 900                     closeConnection();// 关闭连接
 901                     closeServer();//关闭服务程序
 902                 }
 903                 System.exit(0);// 退出程序
 904             }
 905         });
 906         Login();
 907     }
 908 
 909     /**
 910      * 连接服务器
 911      *
 912      * @param port
 913      * @param hostIp
 914      * @param name
 915      */
 916     public boolean connectServer(int port, String hostIp, String name) {
 917         // 连接服务器
 918         try {
 919             socket = new Socket(hostIp, port);// 根据端口号和服务器ip建立连接
 920             writer = new PrintWriter(socket.getOutputStream());
 921             reader = new BufferedReader(new InputStreamReader(socket
 922                     .getInputStream()));
 923             // 发送客户端用户基本信息(用户名和ip地址)
 924             sendMessage(name + "#" + socket.getLocalAddress().toString());
 925             // 开启接收消息的线程
 926             messageThread = new MessageThread(reader, textArea);
 927             messageThread.start();
 928             isConnected = true;// 已经连接上了
 929             return true;
 930         } catch (Exception e) {
 931             textArea.append("与端口号为:" + port + "    IP地址为:" + hostIp
 932                     + "   的服务器连接失败!" + "\r\n");
 933             isConnected = false;// 未连接上
 934             return false;
 935         }
 936     }
 937 
 938     /**
 939      * 发送消息
 940      *
 941      * #param message
 942      */
 943     public void sendMessage(String message) {
 944         writer.println(message);
 945         writer.flush();
 946     }
 947 
 948     /**
 949      * 客户端主动关闭连接
 950      */
 951     @SuppressWarnings("deprecation")
 952     public synchronized boolean closeConnection() {
 953         try {
 954             sendMessage("CLOSE");// 发送断开连接命令给服务器
 955             messageThread.stop();// 停止接受消息线程
 956             // 释放资源
 957             if (reader != null) {
 958                 reader.close();
 959             }
 960             if (writer != null) {
 961                 writer.close();
 962             }
 963             if (socket != null) {
 964                 socket.close();
 965             }
 966             isConnected = false;
 967             listModel.removeAllElements();
 968             return true;
 969         } catch (IOException e1) {
 970             e1.printStackTrace();
 971             isConnected = true;
 972             return false;
 973         }
 974     }
 975 
 976     // 不断接收消息的线程
 977     class MessageThread extends Thread {
 978         private BufferedReader reader;
 979         private JTextArea textArea;
 980 
 981         // 接收消息线程的构造方法
 982         public MessageThread(BufferedReader reader, JTextArea textArea) {
 983             this.reader = reader;
 984             this.textArea = textArea;
 985         }
 986 
 987         // 被动的关闭连接
 988         public synchronized void closeCon() throws Exception {
 989             // 清空用户列表
 990             listModel.removeAllElements();
 991             // 被动的关闭连接释放资源
 992             if (reader != null) {
 993                 reader.close();
 994             }
 995             if (writer != null) {
 996                 writer.close();
 997             }
 998             if (socket != null) {
 999                 socket.close();
1000             }
1001             isConnected = false;// 修改状态为断开
1002 
1003         }
1004 
1005         public void run() {
1006             String message = "";
1007             while (true) {
1008                 try {
1009                     message = reader.readLine();
1010                     StringTokenizer stringTokenizer = new StringTokenizer(
1011                             message, "/#");
1012                     String command = stringTokenizer.nextToken();// 命令
1013                     if (command.equals("CLOSE"))// 服务器已关闭命令
1014                     {
1015                         textArea.append("服务器已关闭!\r\n");
1016                         closeCon();// 被动的关闭连接
1017                         JOptionPane.showMessageDialog(frame, "服务器已关闭!", "错误",
1018                                 JOptionPane.ERROR_MESSAGE);
1019                         frame.setVisible(false);
1020                         textArea.setText("");
1021                         loginframe.setVisible(true);
1022                         return;// 结束线程
1023                     } else if (command.equals("ADD")) {// 有用户上线更新在线列表
1024                         String username = "";
1025                         String userIp = "";
1026                         if ((username = stringTokenizer.nextToken()) != null
1027                                 && (userIp = stringTokenizer.nextToken()) != null) {
1028                             User user = new User(username, userIp);
1029                             onLineUsers.put(username, user);
1030                             listModel.addElement(username);
1031                         }
1032                     } else if (command.equals("DELETE")) {// 有用户下线更新在线列表
1033                         String username = stringTokenizer.nextToken();
1034                         User user = (User) onLineUsers.get(username);
1035                         onLineUsers.remove(user);
1036                         listModel.removeElement(username);
1037                     } else if (command.equals("USERLIST")) {// 加载在线用户列表
1038                         listModel.removeAllElements();
1039                         listModel.addElement("全部用户");
1040                         StringTokenizer strToken ;
1041                         String user ;// 命令
1042                         int size = Integer
1043                                 .parseInt(stringTokenizer.nextToken());
1044                         String username = null;
1045                         String userIp = null;
1046                         for (int i = 0; i < size-1; i++) {
1047                             username = stringTokenizer.nextToken();
1048                             strToken = new StringTokenizer(username, "---()");
1049                             if (strToken.nextToken().equals(frame.getTitle())) {
1050                                 continue;
1051                             }else{
1052                                 listModel.addElement(username);
1053                             }
1054                             //userIp = stringTokenizer.nextToken();
1055                             //User user = new User(username, userIp);
1056                             //onLineUsers.put(username, user);
1057                         }
1058                     } else if (command.equals("MAX")) {// 人数已达上限
1059                         textArea.append(stringTokenizer.nextToken()
1060                                 + stringTokenizer.nextToken() + "\r\n");
1061                         closeCon();// 被动的关闭连接
1062                         JOptionPane.showMessageDialog(frame, "服务器缓冲区已满!", "错误",
1063                                 JOptionPane.ERROR_MESSAGE);
1064                         return;// 结束线程
1065                     } else if(command.equals("FILE")){
1066                         int portNumber = Integer.parseInt(stringTokenizer.nextToken());
1067                         String fileName = stringTokenizer.nextToken();
1068                         long fileSize = Long.parseLong(stringTokenizer.nextToken());
1069                         String ip = stringTokenizer.nextToken();
1070                         String Nickname = stringTokenizer.nextToken();
1071                         ReceiveFileThread receiveFile = new ReceiveFileThread(textArea,frame,ip, portNumber, fileName, fileSize, Nickname);
1072                         receiveFile.start();
1073                         textArea.append("从"+Nickname+"接受文件:"+fileName+",大小为:"+fileSize
1074                                 +"ip:"+ip+"port:"+portNumber+"\r\n");
1075                     }else if(command.equals("USERLOGIN")){
1076                         String st = stringTokenizer.nextToken();
1077                         if(st.equals("OK")){
1078                             JOptionPane.showMessageDialog(loginframe, "登陆成功!" );
1079                             loginframe.setVisible(false);
1080                             txt_name.setText(txt_login_name.getText());
1081                             frame.setVisible(true);
1082                             int count = stringTokenizer.countTokens();
1083                             while(true){
1084                                 if(count==0){
1085                                     break;
1086                                 }
1087                                 textArea.append(stringTokenizer.nextToken()+"  对你留言 ,");
1088                                 textArea.append("时间: "+stringTokenizer.nextToken()+"\r\n   ");
1089                                 textArea.append("留言内容: "+stringTokenizer.nextToken()+"\r\n");
1090                                 count-=3;
1091                             }
1092 
1093                         }else if(st.equals("ALREADY")){
1094                             JOptionPane.showMessageDialog(loginframe, "账号已登陆!" );
1095                         }else{
1096                             JOptionPane.showMessageDialog(loginframe, "登陆失败!" );
1097                         }
1098                     }else if(command.equals("USERZHUCE")){
1099                         String st = stringTokenizer.nextToken();
1100                         if(st.equals("OK")){
1101                             JOptionPane.showMessageDialog(loginframe, "注册成功!" );
1102 
1103                         }else if(st.equals("exict")){
1104                             JOptionPane.showMessageDialog(loginframe, "用户名已存在!" );
1105                         }else{
1106                             JOptionPane.showMessageDialog(loginframe, "注册失败!" );
1107                         }
1108                     }else if(command.equals("USERFORGET")){
1109                         String st = stringTokenizer.nextToken();
1110                         if(st.equals("OK")){
1111                             JOptionPane.showMessageDialog(loginframe, "修改密码成功!" );
1112 
1113                         }else if(st.equals("YOUXIANG_WRONG")){
1114                             JOptionPane.showMessageDialog(loginframe, "邮箱错误!" );
1115                         }else if(st.equals("NAME_NO_exict")){
1116                             JOptionPane.showMessageDialog(loginframe, "用户不存在!" );
1117                         }else{
1118                             JOptionPane.showMessageDialog(loginframe, "找回密码失败!" );
1119                         }
1120                     } else if (command.equals("P2P")) {
1121                         String st = stringTokenizer.nextToken();
1122                         if(st.equals("OK")){
1123                             String username = stringTokenizer.nextToken();
1124                             int serverPort = Integer.parseInt(stringTokenizer.nextToken());
1125                             String ip = stringTokenizer.nextToken();
1126                             boolean cn = connectServer_p2p(serverPort,ip,username);
1127                             if (cn) {
1128                                 JOptionPane.showMessageDialog(frame, "与"+username+"的连接成功,端口号为:"+serverPort+"IP:"+ip );
1129                                 P2P_printWriter.println(frame.getTitle()+"#"+myIP);
1130                                 P2P_printWriter.flush();
1131 
1132                                 String msg = textField.getText().trim();
1133                                 P2P_printWriter.println(msg);
1134                                 P2P_printWriter.flush();
1135 
1136                                 textArea.append("对  "+username+"  说: "+msg+"\r\n");
1137 
1138                                 textField.setText(null);
1139                             }
1140 
1141                         }else{
1142                             String username = stringTokenizer.nextToken();
1143                             JOptionPane.showMessageDialog(frame, "与"+username+"的连接失败!");
1144                         }
1145                     } else {// 普通消息
1146                         textArea.append(message + "\r\n");
1147                     }
1148                 } catch (IOException e) {
1149                     e.printStackTrace();
1150                 } catch (Exception e) {
1151                     e.printStackTrace();
1152                 }
1153             }
1154         }
1155     }
1156 }
  1 package com.company;
  2 
  3 import javax.swing.*;
  4 import java.io.*;
  5 import java.net.ServerSocket;
  6 import java.net.Socket;
  7 
  8 
  9 public class SendFileThread extends Thread {
 10     private Socket clientSocket;
 11     private String name;
 12     JFileChooser sourceFileChooser;
 13     int status;
 14     JFrame JFrame;
 15 
 16     public SendFileThread(JFrame frame, Socket socket, String name, JFileChooser sourceFileChooser, int status) {
 17         this.clientSocket = socket;
 18         this.name = name;
 19         this.sourceFileChooser = sourceFileChooser;
 20         this.status = status;
 21         this.JFrame = frame;
 22     }
 23 
 24     public void run() {
 25 //        JFileChooser sourceFileChooser = new JFileChooser(".");
 26 //        sourceFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
 27 //        int status = sourceFileChooser.showOpenDialog(null);
 28         if (status == JFileChooser.APPROVE_OPTION) {
 29             File sourceFile = new File(sourceFileChooser.getSelectedFile().getPath());
 30             String sourceFilePath = sourceFile.getAbsolutePath();
 31             String fileName = sourceFile.getName();
 32             //System.out.println(sourceFilePath+"\\"+fileName);
 33             try {
 34                 PrintWriter sendToClient = new PrintWriter(clientSocket.getOutputStream());
 35                 BufferedReader getFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
 36                 ServerSocket fileSenderSocket = null;
 37                 try {
 38                     fileSenderSocket = new ServerSocket(0);
 39                 } catch (IOException ex1) {
 40                     JOptionPane.showMessageDialog(JFrame, "无法分配端口以发送此文件!", "错误", JOptionPane.ERROR_MESSAGE);
 41                 }
 42                 sendToClient.println("FILE#" + fileSenderSocket.getLocalPort() + "#" + fileName + "#"
 43                         + String.valueOf(sourceFile.length()) + "#" + clientSocket.getLocalAddress() + "#" + name);
 44                 sendToClient.flush();
 45                 //System.out.println("Sender: "+fileSenderSocket.getLocalSocketAddress());
 46                 Socket fileReceiverSocket = fileSenderSocket.accept();
 47 
 48                 BufferedReader getFromReceiver = null;
 49                 PrintWriter sendToReceiver = null;
 50                 try {
 51                     getFromReceiver = new BufferedReader(new InputStreamReader(fileReceiverSocket.getInputStream()));
 52                     sendToReceiver = new PrintWriter(fileReceiverSocket.getOutputStream());
 53                 } catch (IOException ex) {
 54                 } finally {
 55                 }
 56                 String judge = getFromReceiver.readLine();
 57                 if (judge.equals("accepted")) {
 58                     DataOutputStream sendFileToReceiver = new DataOutputStream(new BufferedOutputStream(fileReceiverSocket.getOutputStream()));
 59                     ProgressMonitorInputStream monitor;
 60                     FileInputStream sendFileStream = null;
 61                     try {
 62                         sendFileStream = new FileInputStream(sourceFile);
 63                     } catch (FileNotFoundException ex) {
 64                         sendToReceiver.flush();
 65                         sendFileToReceiver.writeByte(0);
 66                         sendFileToReceiver.flush();
 67                         return;
 68                     }
 69                     monitor = new ProgressMonitorInputStream(JFrame, "正在发送: " + fileName, sendFileStream);
 70                     ProgressMonitor progressMonitor = monitor.getProgressMonitor();
 71 
 72                     int read_unit = 500;
 73                     long fileSize = monitor.available();
 74                     int readed = 0;
 75                     byte[] data = new byte[read_unit];
 76                     try {
 77                         sendFileToReceiver.writeByte(1);
 78                         sendFileToReceiver.flush();
 79                         while (monitor.available() > 0) {
 80                             int in = monitor.read(data);
 81                             readed += in;
 82                             float process = (float) readed / fileSize * 100;
 83                             progressMonitor.setNote(process + " % 完成");
 84                             if (in > 0) {
 85                                 sendFileToReceiver.write(data, 0, in);
 86                             }
 87                         }
 88                         sendFileToReceiver.flush();
 89                     } catch (IOException e) {
 90                         JOptionPane.showMessageDialog(JFrame, "传输中断!", "错误", JOptionPane.ERROR_MESSAGE);
 91                     } finally {
 92                         if (sendFileStream != null)
 93                             try {
 94                                 sendFileStream.close();
 95                                 monitor.close();
 96                             } catch (IOException e) {
 97                             }
 98                     }
 99                     try {
100                         fileReceiverSocket.close();
101                     } catch (IOException ex1) {
102                     }
103                 } else if (judge.equals("refused")) {
104                     JOptionPane.showMessageDialog(JFrame, "对方拒绝接受文件 " + fileName, "错误!", JOptionPane.INFORMATION_MESSAGE);
105                 }
106 
107             } catch (IOException ex) {
108             } finally {
109             }
110         }
111     }
112 }
View Code
  1 package com.company;
  2 import java.io.BufferedInputStream;
  3 import java.io.BufferedOutputStream;
  4 import java.io.BufferedReader;
  5 import java.io.DataInputStream;
  6 import java.io.DataOutputStream;
  7 import java.io.File;
  8 import java.io.FileOutputStream;
  9 import java.io.IOException;
 10 import java.io.InputStreamReader;
 11 import java.io.PrintWriter;
 12 import java.net.Socket;
 13 
 14 import javax.swing.JFileChooser;
 15 import javax.swing.JFrame;
 16 import javax.swing.JOptionPane;
 17 import javax.swing.JTextArea;
 18 import javax.swing.ProgressMonitor;
 19 import javax.swing.ProgressMonitorInputStream;
 20 
 21 
 22 public class ReceiveFileThread extends Thread {
 23     private String fileSenderIPAddress;
 24     private int fileSenderPortNumber;
 25     private String fileName;
 26     private long fileSize;
 27     private String otherNickname;
 28     JFrame frame;
 29     JTextArea textArea;
 30 
 31     public ReceiveFileThread(JTextArea textArea,JFrame frame,String ip, int port_number, String file_name, long file_size, String other_nickname) {
 32         this.fileSenderIPAddress = ip;
 33         this.fileSenderPortNumber = port_number;
 34         this.fileName = file_name;
 35         this.fileSize = file_size;
 36         this.otherNickname = other_nickname;
 37         this.frame = frame;
 38         this.textArea = textArea;
 39     }
 40 
 41     public void run() {
 42         Socket fileSenderSocket = null;
 43         try {
 44             fileSenderSocket = new Socket(fileSenderIPAddress, fileSenderPortNumber);
 45         }
 46         catch(IOException ex) {
 47             JOptionPane.showMessageDialog(frame, "无法连接到服务器接收文件!", "错误", JOptionPane.ERROR_MESSAGE);
 48         }
 49         finally {
 50         }
 51         DataInputStream getFromSender = null;
 52         DataOutputStream sendToSender = null;
 53         try {
 54             getFromSender = new DataInputStream(new BufferedInputStream(fileSenderSocket.getInputStream()));
 55             sendToSender = new DataOutputStream(new BufferedOutputStream(fileSenderSocket.getOutputStream()));
 56             BufferedReader getInfoFromSender =new BufferedReader(new InputStreamReader(getFromSender));
 57 
 58             int permit = JOptionPane.showConfirmDialog(frame, "接受文件:"+fileName+" 从 "+otherNickname+"?", "文件传输请求:", JOptionPane.YES_NO_OPTION);
 59             if(permit == JOptionPane.YES_OPTION) {
 60                 sendToSender.writeBytes("accepted\n");
 61                 sendToSender.flush();
 62 
 63                 JFileChooser destinationFileChooser = new JFileChooser(".");
 64                 destinationFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
 65                 int status = destinationFileChooser.showSaveDialog(frame);
 66                 File destinationPath = null;
 67                 if (status == JFileChooser.APPROVE_OPTION) {
 68                     destinationPath = new File(destinationFileChooser.getSelectedFile().getPath());
 69                     //String destinationFile = destinationPath.getAbsolutePath()+"\\"+fileName;
 70                     //System.out.println(destinationFilePath);
 71                 }
 72                 try {
 73                     byte judge = getFromSender.readByte();
 74                     if (judge > 0) {
 75                         File savedFile = new File(destinationPath.getAbsolutePath()+"\\"+fileName);
 76                         FileOutputStream saveFileStream = new FileOutputStream(savedFile);
 77                         DataOutputStream fileOutput = new DataOutputStream(saveFileStream);
 78                         ProgressMonitorInputStream monitor = new ProgressMonitorInputStream(frame, "接受文件: "+fileName, getFromSender);
 79                         //ProgressMonitor progressMonitor = new ProgressMonitor(null, "Receiving "+fileName, "", 0, (int)fileSize);
 80                         ProgressMonitor progressMonitor = monitor.getProgressMonitor();
 81                         progressMonitor.setMaximum((int)fileSize);
 82 
 83                         int read_unit = 500;
 84                         int readed = 0;
 85                         float process = 0;
 86                         try {
 87                             while (true) {
 88                                 byte[] data = new byte[read_unit];
 89                                 int in = monitor.read(data);
 90                                 readed += in;
 91                                 process = (float) readed / fileSize * 100;
 92                                 progressMonitor.setNote(process+" % 完成");
 93                                 progressMonitor.setProgress(readed);
 94                                 if (in <= 0) {
 95                                     break;
 96                                 }
 97                                 fileOutput.write(data,0,in);
 98                             }
 99 
100                             fileOutput.flush();
101                             if(savedFile.length() < fileSize) {
102                                 JOptionPane.showMessageDialog(frame, "传输中断!", "错误", JOptionPane.ERROR_MESSAGE);
103                             }
104                             textArea.append("接受文件:"+fileName+"    保存地址:"+destinationPath+"\r\n");
105                         }
106                         catch(IOException e){
107                             JOptionPane.showMessageDialog(frame, "传输中断!", "错误", JOptionPane.ERROR_MESSAGE);
108                         }
109                         finally {
110                             try {
111                                 fileOutput.close();
112                                 saveFileStream.close();
113                                 progressMonitor.close();
114                             }
115                             catch(IOException e){
116                             }
117                         }
118                     }
119                     else {
120                         JOptionPane.showMessageDialog(frame, "源文件没有找到!", "错误", JOptionPane.ERROR_MESSAGE);
121                     }
122                 }
123                 catch(IOException e){
124                 }
125                 finally {
126                     fileSenderSocket.close();
127                 }
128             }
129             else if(permit == JOptionPane.NO_OPTION) {
130                 sendToSender.writeBytes("refused\n");
131                 sendToSender.flush();
132             }
133         }
134         catch(IOException ex) {
135         }
136         finally {
137         }
138         //System.out.println("Receiver: "+fileReceiverSocket.getRemoteSocketAddress());
139     }
140 
141 }
View Code
 1 package com.company;
 2 
 3 //用户信息类
 4 public class User{
 5     private String name;
 6     private String ip;
 7     private int state;
 8 
 9     public User(String name, String ip) {
10         this.name = name;
11         this.ip = ip;
12     }
13 
14     public String getName() {
15         return name;
16     }
17 
18     public void setName(String name) {
19         this.name = name;
20     }
21 
22     public String getIp() {
23         return ip;
24     }
25 
26     public void setIp(String ip) {
27         this.ip = ip;
28     }
29 
30     public int getState() {
31         return state;
32     }
33 
34     public void setState(int state){
35         this.state=state;
36     }
37 }
View Code

 

 

是一次实验课的第一次实验,可能还有bug,请理解!

 

后期会更新。