zoukankan      html  css  js  c++  java
  • java 通过TCPUDP 协议实现多人聊天,点对点,文件传送-----分服务器端和客户端

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

     

      启动界面如下图:

     

     

     

    首先启动服务器:

     

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

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

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

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

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

    消息发送演示

     服务器端代码:

       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() + "
    ");
     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() + "
    ");
     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                             + "
    ");
     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("服务器成功停止!
    ");
     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 + "
    ");
     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 + "
    ");
     684             } else {
     685                 contentArea.append("对  " + user_name + "  说:" + message + "
    ");
     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() + "上线!
    ");
     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() + "下线!
    ");
     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 + "
    ");
     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 + "  修改密码!
    ");
     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 + "
    ");
    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+"
    ");
    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                     + "   的服务连接失败!" + "
    ");
     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服务已关闭!
    ");
     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+"
    ");
     219                     } else {// 普通消息
     220                         textArea.append(""+message + "
    ");
     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+"
    ");
     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() + "建立连接成功!
    ");
     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+"
    ");
     342                     }else {
     343                         textArea.append(user.getName()+"  对你说: "+message+"
    ");
     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链接
    ");
     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() + "
    ");
     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() + "
    ");
     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() + "
    ");
     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+"
    ");
     444                         clients.get(i).writer_ptp.flush();
     445                         textArea.append("对  "+user_name+"  说: "+message+"
    ");
     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+"
    ");
     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+"
    ");
     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                     + "   的服务器连接失败!" + "
    ");
     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("服务器已关闭!
    ");
    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() + "
    ");
    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+"
    ");
    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()+"
       ");
    1089                                 textArea.append("留言内容: "+stringTokenizer.nextToken()+"
    ");
    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+"
    ");
    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 + "
    ");
    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
    ");
     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+"
    ");
    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
    ");
    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,请理解!

    后期会更新。

  • 相关阅读:
    改变对象的字符串提示
    perl 和 python中的回调函数
    shiro权限验证标签
    user_tables 的信息依赖于统计信息
    centos jdk 1.7升级到1.8后显示还是1.7
    7.1 可接受任意数量参数的函数:
    IntelliJ IDEA中怎么查看文件中所有方法(类似eclipse里面的outline)
    Intellij IDEA 代码格式化与eclipse保持风格一致
    jquery-1.9.1.min.js:69 Uncaught TypeError: Illegal invocation
    python json模块
  • 原文地址:https://www.cnblogs.com/alimjan/p/7798295.html
Copyright © 2011-2022 走看看