数据结构和算法, 我还没明白

永远的C

博客园 首页 新随笔 联系 订阅 管理
package com.chat.client;

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import com.chat.util.WindowTool;

/**
* 客户端登录窗口类, 用来验证登录和注册用户.
*
@author 刘优
*
*/
public class ClientLogin extends JDialog implements ActionListener,KeyListener {

   
private static final long serialVersionUID = 1L;
   
private JTextField username;                    // 用户名输入框
    private JPasswordField password;                // 密码输入框
    private BufferedReader theReader; // 从服务器读数据的对象
    private PrintWriter theWriter; // 往服务器写数据的对象
    private ChatClient client;                        // 此窗口所属的CLIENT对象

   
/**
     * 初始化此窗口
     *
@param owner
     *
@param title
     *
@param modal
     *
@param theReader
     *
@param theWriter
     *
@throws HeadlessException
    
*/
   
public ClientLogin(ChatClient owner, String title, boolean modal,BufferedReader theReader,PrintWriter theWriter) throws HeadlessException {
       
super(owner, title, modal);
       
this.client = owner;
       
this.theReader = theReader;
       
this.theWriter = theWriter;
       
//初始化图形界面

        setLayout(
new BorderLayout());
        JPanel main
= new JPanel(new GridLayout(2,2));
        JLabel title1
= new JLabel("登录信息 : ",JLabel.CENTER);
        JLabel l1
= new JLabel("        姓名 : ");
        JLabel l2
= new JLabel("        密码 : ");
        username
= new JTextField();
        password
= new JPasswordField();
        username.addKeyListener(
this);
        password.addKeyListener(
this);
        JButton ok
= new JButton("登录");
        JButton register
= new JButton("注册");
        JButton cancel
= new JButton("取消");

        ok.setActionCommand(
"login");
        register.setActionCommand(
"register");
        cancel.setActionCommand(
"cancel");

        ok.addActionListener(
this);
        register.addActionListener(
this);
        cancel.addActionListener(
this);
        main.add(l1);
        main.add(username);
        main.add(l2);
        main.add(password);
        JPanel buttonPane
= new JPanel();
        buttonPane.add(ok);
        buttonPane.add(register);
        buttonPane.add(cancel);
        add(title1,
"North");
        add(main);
        add(buttonPane,
"South");
        WindowTool.doView(
this,230,130); // 居中显示

    }

   
/**
     * 验证用户
     *
@return String
    
*/
   
public int verify() {
       
return verify(username.getText(),new String(password.getPassword()));
    }
   
/**
     * 把登录信息发送到服务器端, 格式为login=用户名=密码
     *
@param username
     *
@param password
     *
@return
    
*/
   
private int verify(String username,String password) {
        theWriter.println(
"login=" + username + "=" + password);
        theWriter.flush();
        String infor
= null;
       
try {
            infor
= theReader.readLine();
           
while (!infor.startsWith("login="))
            {
                infor
= theReader.readLine();
            }
           
//System.out.println(infor);
        } catch (IOException e) {
            e.printStackTrace();
        }
       
int rs = -1;
       
try {
            rs
= Integer.parseInt(infor.substring(6));
        }
       
catch (Exception e) {e.printStackTrace();}
       
return rs;

    }
   
public void actionPerformed(ActionEvent e) {
        String cmd
= e.getActionCommand();
       
if (cmd.equals("login")) {
            login();
        }
       
else if (cmd.equals("cancel")) {
            System.exit(
0);
        }
       
else if (cmd.equals("register")) {
            register();
        }
    }
   
/**
     * 注册新用户 格式为register=用户名=密码
     *
    
*/
   
private void register() {
       
if (username.getText().length() == 0 || password.getPassword().length == 0) {
            alarm(
"姓名和密码不能为空!");
           
return;
        }
        theWriter.println(
"register=" + username.getText() + "=" + new String(password.getPassword()));
        theWriter.flush();
        String infor
= null;
       
try {
            infor
= theReader.readLine();
        }
catch (IOException e) {
            e.printStackTrace();
        }
       
if (infor.startsWith("register=")) {
           
if (infor.endsWith("1")) {
                alarm(
"注册新用户成功,请登录...");
               
return;
            }
        }
        alarm(
"用户名已存在, 注册新用户失败,请重试...");
    }
   
/**
     * 登录服务器
     *
    
*/
   
private void login() {
       
if (username.getText().length() == 0) {
            alarm(
"姓名不能为空!");
           
return;
        }
       
if (password.getPassword().length == 0) {
            alarm(
"密码不能为空!");
           
return;
        }
       
int verifyrs = verify();
       
if (verifyrs == 0) {
            ((ChatClient)
this.getOwner()).start(username.getText());        // 用户登录成功!启动ChatClient对象
            this.dispose();                                                    // 把此窗口销毁
        }
       
else {
            String infor
= null;
           
switch (verifyrs) {
               
case -1 :
                    infor
= "未知错误";
                   
break;
               
case 1 :
                    infor
= "缺少用户名";
                   
break;
               
case 2 :
                    infor
= "缺少密码";
                   
break;
               
case 3 :
                    infor
= "用户已经登录";
                   
break;
               
case 4 :
                    infor
= "用户名错误";
                   
break;
               
case 5 :
                    infor
= "密码错误";
                   
break;
            }
            alarm(infor);            
// 如果失败, 提示失败详细信息
        }
    }
   
private void alarm(String infor) {
        client.alarm(infor,
true);
    }
   
public void keyTyped(KeyEvent e) {

    }
   
/**
     * 键盘监听响应
    
*/
   
public void keyPressed(KeyEvent e) {
       
if (e.getKeyCode() == 10) {            // 响应回车, 输完用户名回车, 输入焦点转移到密码框上, 如果输完密码回车, 则直接登录
            if (e.getSource() == username) {
                password.requestFocus();
            }
           
else {
                login();
            }
        }

    }
   
public void keyReleased(KeyEvent e) {
       
// 没啥用
    }

}


package com.chat.client;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.Iterator;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import com.chat.util.TimeBean;
import com.chat.util.WindowTool;

/**
* 客户端JFRAME 主窗口
*
@author 刘优
*
*/
public class ChatClient extends JFrame implements Runnable,ActionListener,KeyListener {
   
private static final long serialVersionUID = 1L;
   
private static final String AUTHOR = "作者:刘优 版本:1.0";
   
private ClientLogin login;
   
private JTextArea main;                                        // 显示消息的主窗口
    private JTextField input;                                    // 用户输入栏
    private JComboBox usersCombo;                                // 其他所有用户控件
    private JScrollBar mainVerticalBar;
   
private JLabel timer;                                        // 时间显示标签
    private int width = 900;                                    // 窗口宽度
    private int height = 600;                                    // 窗口高度
    private JButton blackButton;                                // 黑名单按钮
    private JButton friendButton;                                // 好友按钮
    private JButton connectButton;                                // 连接按钮
    private JDialog dialog;                                        // 消息子窗口
    private Container dialogPane;
   
private JLabel alarmLabel2;                                    // 消息标签
    private JLabel alarmLabel;
   
private JLabel myNameLabel;
   
private int dialogRs;                                        // 消息窗口返回值
    private JPanel sPane;
   
private JButton cl;                                            // 消息窗口取消按钮
    private String welcome;

   
private Socket socket;                                        // 套接字
    private String ip;
   
private int port;
   
private InputStream inputStream;
   
private OutputStream outputStream;
   
private BufferedReader theReader;                            // 字符流输入对象
    private PrintWriter theWriter;                                // 字符流输出对象
    private boolean read;                                        // 客户端运行标志
    private String myName;                                        // 客户端用户名
    private HashSet<String> allusers;                            // 其他所有用户名
    private String toUser = "所有人";                            // 发送悄悄话的用户名
    private String toUser2 = "所有人";
   
private String sendFileName;                                // 要发送的文件名
    private int sendFilePort;                                    // 发送文件用的端口
    private int bufferSize = 8193;                                // 发送文件时用的缓冲区大小
    private HashSet<String> myfriends;                            // 我的好友列表
    private boolean uiReady;
   
private boolean connected;

   
private static String encode = "UTF-8";

   
public ChatClient(String ip, int port) throws UnknownHostException, IOException {
       
super("ChatRoom - ");
       
this.ip = ip;
       
this.port = port;
        createDialog();
        connect();
    }

   
private void createDialog() {
       
// 构建消息窗口, 但不显示, 如果有提示信息则显示.
       
// 为了使之反应更快

        dialog
= new JDialog(this,"消息窗口",true);
        dialog.setSize(
500,150);
        dialog.setLocation(
this.getX() + 100, this.getY() + 100);
        dialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
        dialog.setResizable(
false);
        dialogPane
= dialog.getContentPane();
        alarmLabel
= new JLabel("信息",JLabel.CENTER);
        dialog.setTitle(
"信息");

        alarmLabel2
= new JLabel("",JLabel.CENTER);
        alarmLabel2.setFont(
new Font("宋体",Font.BOLD,16));
        alarmLabel2.setForeground(Color.red);
        dialogPane.add(alarmLabel,
"North");
        dialogPane.add(alarmLabel2);

        JButton b
= new JButton("确定");
        b.addActionListener(
new ActionListener() {
           
public void actionPerformed(ActionEvent ae) {
                dialog.setVisible(
false);
                sPane.remove(cl);
            }
        });
        sPane
= new JPanel();
        sPane.add(b);
        cl
= new JButton("取消");
        cl.addActionListener(
new ActionListener() {
           
public void actionPerformed(ActionEvent ae) {
                dialogRs
= 1;
                dialog.setVisible(
false);
                sPane.remove(cl);
            }
        });
        dialogPane.add(sPane,
"South");
    }
   
/**
     * 连接服务器, 需要提供IP和端口.
     *
@throws UnknownHostException
     *
@throws IOException
    
*/
   
private void connect() throws UnknownHostException, IOException {
       
try {
            socket
= new Socket(ip,port);            // 连接服务器
        }
       
catch (Exception e) {
            alarm(
"服务器未准备就绪!",true);            // 后面的TRUE表明提示信息很严重
            return;
        }
        inputStream
= socket.getInputStream();        // 获取输入流
        outputStream = socket.getOutputStream();    // 获取写服务器的输出流
        theReader = new BufferedReader(new InputStreamReader(inputStream,encode));            //包装一下
        theWriter = new PrintWriter(new OutputStreamWriter(outputStream,encode),true);        //包装一下
        welcome = theReader.readLine();                // 读取欢迎信息, 不显示, 没啥用TERM端会有用
        welcome = theReader.readLine();
        theWriter.println(
"client=window");            //告诉服务器, 客户端类型为window
        theWriter.flush();

       
// 启动验证登录窗口
        login = new ClientLogin(this,"登录",true,theReader,theWriter);

    }

   
private void uiInit() {
        uiReady
= true;
        main
= new JTextArea();
        main.setEditable(
false);                                        // 不允许编辑主窗口
        input = new JTextField(30);
        input.setFont(
new Font("宋体",Font.PLAIN,14));
        input.addKeyListener(
this);
        JScrollPane scroll1
= new JScrollPane(main);
        mainVerticalBar
= scroll1.getVerticalScrollBar();
        JPanel northPane
= new JPanel();
        JLabel title
= new JLabel("欢迎使用");
        JLabel timeInherit
= new JLabel("系统当前时间 : ");
        timer
= new JLabel();
        TimeBean.setLabel(timer);
        northPane.add(title);
        northPane.add(timeInherit);
        northPane.add(timer);
        northPane.add(
new JLabel(" 日期 : " + TimeBean.getDate()));         // 获取当前时间并显示

        JPanel southPane
= new JPanel();
        usersCombo
= new JComboBox();                                    // 所有用户列表

        usersCombo.addActionListener(
this);
        JButton send
= new JButton("消息");
        JButton sendfile
= new JButton("文件");
        friendButton
= new JButton("好友");
        blackButton
= new JButton("屏蔽");
        connectButton
= new JButton("断开");
        sendfile.addActionListener(
this);
        send.addActionListener(
this);
        connectButton.addActionListener(
this);
        friendButton.addActionListener(
this);
        blackButton.addActionListener(
this);

        myNameLabel
= new JLabel();
        southPane.add(myNameLabel);
        southPane.add(usersCombo);
        southPane.add(input);
        southPane.add(send);
        southPane.add(sendfile);
        southPane.add(friendButton);
        southPane.add(blackButton);
        southPane.add(connectButton);

       
this.add(northPane,"North");
       
this.add(scroll1);
       
this.add(southPane,"South");
        WindowTool.doView(
this,width,height);

       
this.addWindowListener(new WindowAdapter() {
           
public void windowClosing(WindowEvent we) {
                close(
false,true);
            }
        });
    }

    /**
     * 用户登录成功开始主方法
     *
@param username
    
*/
   
public void start(String username) {
       
if (login != null) {
            login.dispose();
        }
        allusers
= new HashSet<String>();
        myfriends
= new HashSet<String>();
        myName
= username;
       
if (!uiReady) {
            uiInit();
        }
        setTitle(
"ChatRoom - " + username + "        " + AUTHOR);    // 设置标题
        myNameLabel.setText("[" + username + "]对:");                // 显示我是谁
        connectButton.setText("断开");                                // 设置按纽文本
        sendFilePort = 9999;                                        // 文件发送和接收端口
        work();                                                        // 开始工作啦
    }

   
private void work() {
        Thread readThread
= new Thread(this);                        // 新建一个线程来工作
        read = true;
        readThread.start();
    }
   
/**
     * 显示警告信息
     *
@param infor
    
*/
   
public void alarm(String infor) {
        dialogRs
= 0;
        alarm(infor,
false);
    }
   
public void alarm(String infor,boolean serious) {
       
if (serious) {
            dialog.setTitle(
"错误!!");
            alarmLabel
= new JLabel("发生错误 : ",JLabel.CENTER);
        }
        alarmLabel2.setText(infor);
        WindowTool.doView(dialog,
350,110);
    }
   
/**
     * 发送INPUT输入的文本
     *
    
*/
   
private void send() {
       
if (theWriter == null) {
            main.append(
"服务器的连接已断开!!\n");

            alarm(
"服务器的连接已断开",true);
           
return;
        }

       
if (input.getText().length() > 0) {
            String infor
= input.getText();
           
if (!toUser.equals("所有人")) {
                infor
= "to=" + toUser + "=" + infor;    // 发送悄悄话
            }
            theWriter.println(infor);
            theWriter.flush();
            input.setText(
"");
           
if (infor.equals("exit")) {                    // 如果是exit指令则退出系统
                close(false,true);

            }
        }
       
else {
            main.append(
"您还没输入呢\n");                // 提示用户输入后再发送
            mainVerticalBar.setValue(mainVerticalBar.getMaximum()); // 设置主窗口,使之总是能显示最后一行 达到刷新效果
        }
    }
   
/**
     * 处理按纽事件, 根据上面的文本来响应
    
*/
   
public void actionPerformed(ActionEvent e) {
        String cmd
= e.getActionCommand();
       
if (cmd.equals("消息")) {
            send();
        }
       
else if (cmd.equals("文件")) {
            sendFile();
        }
       
else if (cmd.equals("屏蔽")) {
            toBlackList();
        }
       
else if (cmd.equals("解禁")) {
            unBlackUser();
        }
       
else if (cmd.equals("好友")) {
            toFriendList();
        }
       
else if (cmd.equals("陌生")) {
            unFriendUser();
        }
       
else if (cmd.equals("断开")) {
            disconnect();
        }
       
else if (cmd.equals("连接")) {
           
try {
                connect();
            }
catch (UnknownHostException e1) {
                e1.printStackTrace();
            }
catch (IOException e1) {
                e1.printStackTrace();
            }
        }
       
else {
           
// 处理按钮的文本
            Object obj = usersCombo.getSelectedItem();
           
if (obj != null) {
                toUser
= obj.toString();
               
if (!toUser.equals("所有人")) {
                   
if (toUser.startsWith("好友-")) {
                        toUser
= toUser.substring(3);
                    }
                    toUser2
= toUser;
                   
if (theWriter == null) return;
                    theWriter.println(
"isblack=" + toUser);
                    theWriter.flush();
                   
for (String user : myfriends) {
                       
if (user.equals(toUser)) {
                            friendButton.setText(
"陌生");
                           
break;
                        }
                    }
                }
               
else {
                    blackButton.setText(
"屏蔽");
                    friendButton.setText(
"好友");
                }
            }
        }
        input.requestFocus();
    }
   
/**
     * 把用户设为好友
     *
    
*/
   
private void toFriendList() {
       
if (theWriter == null) {
            disconnectAlarm();
           
return;
        }
       
if (toUser.equals("所有人")) {
            alarm(
"请选择目标用户");
           
return;
        }

        theWriter.println(
"setfriend=" + toUser);    // 告诉服务器, 我要把toUser加为发友
        theWriter.flush();
    }
   
private void unFriendUser() {
       
if (theWriter == null) {
            disconnectAlarm();
           
return;
        }
       
if (toUser.equals("所有人")) {
            alarm(
"请选择目标用户");
           
return;
        }
        theWriter.println(
"unfriend=" + toUser);    // 告诉服务器, 我要把toUser从好友中删除
        theWriter.flush();
    }
   
private void disconnectAlarm() {
        main.append(
"服务器的连接已断开!!\n");
        alarm(
"服务器的连接已断开!!",true);
    }
   
private void unBlackUser() {
       
if (theWriter == null) {
            disconnectAlarm();
           
return;
        }
       
if (toUser.equals("所有人")) {
            alarm(
"请选择目标用户");
           
return;
        }
        theWriter.println(
"unblack=" + toUser);        // 告诉服务器, 要把toUser从黑名单中删除
        theWriter.flush();
    }
   
private void toBlackList() {
       
if (theWriter == null) {
            disconnectAlarm();
           
return;
        }
       
if (toUser.equals("所有人")) {
            alarm(
"请选择目标用户");
           
return;
        }
        theWriter.println(
"black=" + toUser);        // 告诉服务器, 要把toUser添加为黑名单
        theWriter.flush();
    }

    /**
     * 给其他用户发送文件 格式为sendfile=filename=myname=tousername
     *
    
*/
   
private void sendFile() {
       
if (theWriter == null) {
            disconnectAlarm();
           
return;
        }
       
if (toUser.equals("所有人")) {
            alarm(
"请选择目标用户");
           
return;
        }
        JFileChooser fileChooser
= new JFileChooser();
       
int returnVal = fileChooser.showOpenDialog(this);
       
if(returnVal == JFileChooser.APPROVE_OPTION) {
            File f
= fileChooser.getSelectedFile();
           
if (!f.canRead()) {
                alarm(
"此文件不可读!"); // 文件不能读, 不能发
                return;
            }
           
if (f.length() == 0) {
                alarm(
"文件大小为零");    // 文件大小为0 发也没意思
                return;
            }
            sendFileName
= f.getPath();
        }
       
if (sendFileName == null) return;
        theWriter.println(
"sendfile=" + sendFileName.substring(sendFileName.lastIndexOf(File.separator) + 1) + "=" + myName + "=" + toUser);
        theWriter.flush();
    }
   
/**
     * 主要的处理方法, 读取并处理服务器发送回来的指令
    
*/
   
public void run() {
       
while (read) {
            String infor
= null;
           
try {
               
if (theReader != null) {
                    infor
= theReader.readLine();
                   
if (infor == null || theReader == null) {
                        close(
true,false);
                    }
                   
if (infor.startsWith("myfriends=")) {                // 获取我的好友名单
                        myfriends.clear();
                        String s
= infor.substring(10).trim();
                        String[] thenames
= s.split(",");
                       
if (s.length() < 2) {
                           
continue;
                        }
                       
for (int j = 0; j != thenames.length; ++j) {
                            myfriends.add(thenames[j]);
                        }
                    }
                   
else if (infor.startsWith("allusers=")) {            // 获取所有用户名
                        allusers.clear();
                        String str
= infor.substring(9);
                        String [] allUserArray
= str.split(",");
                       
for (int i = 0; i != allUserArray.length; ++i) {
                            allusers.add(allUserArray[i]);
                        }
                    }
                   
else if (infor.startsWith("newlogin=")) {            // 新用户登录了
                        String newer = infor.substring(9);
                        allusers.add(newer);
                        handleUsers();
                        infor
= "系统\t[公共] : 用户 : " + newer + " 进入了聊天室";
                    }
                   
else if (infor.startsWith("logout=")) {                // 有用户推出聊天室
                        String username = infor.substring(7);
                       
if (username.equals(myName)) {
                            alarm(
"断开了服务器的连接!!!",true);
                            main.append(
"断开了服务器的连接!!!\n");
                            close(
true,false);
                           
break;
                        }
                        allusers.remove(username.trim());
                        handleUsers();
                        infor
= "系统\t[公共] : 用户 : " + username + " 离开了聊天室";
                    }
                   
else if (infor.startsWith("sendfile=")) {            // 有用户给我发送文件
                        String [] infors = infor.split("=");
                        String fromUser
= infors[2];
                        String toUser
= infors[3];
                        String filename
= infors[1];
                        sPane.add(cl);
                        alarm(
"用户 : " + fromUser + " 想给您发送文件 \"" + filename + "\"  您是否原意接收?");
                       
if (dialogRs == 0) {
                            Thread recFileThread
= null;
                           
try {
                                recFileThread
= new RecFileThread();
                                recFileThread.start();
                            }
catch (Exception e) {
                                dialogRs
= 1;
                                e.printStackTrace();
                            }
                        }
                        theWriter.println(
"recfile=" + filename + "=" + fromUser + "=" + toUser + "=" + dialogRs);
                        theWriter.flush();

                    }
                   
else if (infor.startsWith("recfile=")) {            // 我给别人发送文件的响应
                        String [] infors = infor.split("=");
                        String toUser
= infors[3];
                        String rs
= infors[4];
                        String ip
= infors[5].substring(1);
                       
if (rs.equals("0")) {
                            alarm(
"用户 : " + toUser + " 同意接收您的文件...");
                            Thread sendFile
= new SendFileThread(ip);
                            sendFile.start();
                        }
                       
else {
                            alarm(
"用户 : " + toUser + " 拒绝接收您的文件...");
                        }
                    }
                   
else if (infor.startsWith("black=")) {                // 我被别人踢到黑名单了
                        String other = infor.substring(6);
                        alarm(
"用户 : " + other + " 把您放入了黑名单");
                    }
                   
else if (infor.startsWith("blacksuccess=")) {        // 我把某人踢到黑名单成功
                        String other = infor.substring(13);
                        alarm(
"把用户 : " + other + "添加到黑名单成功!");
                        blackButton.setText(
"解禁");
                    }
                   
else if (infor.startsWith("blacksuccess2=")) {
                        String other
= infor.substring(14);
                        alarm(
"用户 : " + other + "已经在黑名单中了!");
                    }
                   
else if (infor.startsWith("blackfile=")) {
                        String other
= infor.substring(10);
                        alarm(
"用户 : " + other + " 把您放入了黑名单! 无法发送文件!");
                    }
                   
else if (infor.startsWith("isblack=")) {
                        String rs
= infor.substring(8);
                       
if (rs.equals("1")) {
                            blackButton.setText(
"解禁");
                        }
                       
else {
                            blackButton.setText(
"屏蔽");
                        }
                    }
                   
else if (infor.startsWith("unblack=")) {            // 把用户从黑名单中删除
                        String thename = infor.substring(8);
                        alarm(
"用户 : " + thename + " 解禁成功!");
                        blackButton.setText(
"屏蔽");
                    }
                   
else if (infor.startsWith("beblacked=")) {            // 我被别人加入了黑名单:(
                        String thename = infor.substring(10);
                        alarm(
"用户 : " + thename + " 把您放入了黑名单中!");
                    }
                   
else if (infor.startsWith("unblacked=")) {            // 别人把我从黑名单中删除了:)
                        String thename = infor.substring(10);
                        alarm(
"用户 : " + thename + " 把您从黑名单中清除!");
                    }
                   
else if (infor.startsWith("setfriend=")) {            // 别人把我加为好友了
                        String thename = infor.substring(10);
                        alarm(
"用户 : " + thename + " 已被您添加为好友!");
                        myfriends.add(thename);
                        handleUsers();
                    }
                   
else if (infor.startsWith("setfriended=")) {        // 我要把别人加为好友
                        String thename = infor.substring(12);
                        alarm(
"用户 : " + thename + " 把您添加为好友了!");
                        handleUsers();
                    }
                   
else if (infor.startsWith("unfriend=")) {            // 我要把别人从好友中删除
                        String thename = infor.substring(9);
                        myfriends.remove(thename);
                        alarm(
"用户 : " + thename + " 已经从好友中删除了!");
                        handleUsers();
                    }
                   
else if (infor.startsWith("unfriended=")) {            // 别人把我从好友中删除了:(
                        String thename = infor.substring(11);
                        alarm(
"用户 : " + thename + " 把您从好友中删除了!");
                        handleUsers();
                    }
                   
if (infor.indexOf("=") != -1) {                        // 所有的服务器发送的指令都包含=号, 不显示之
                        continue;
                    }
                }
               
else {
                    alarm(
"服务器关闭,程序退出!",true);
                }
            }
catch (IOException e) {
                e.printStackTrace();
            }
            main.append(infor
+ "\t\t[" + TimeBean.getTime() + "]\n");        // 显示新消息(别人的悄悄话, 或是公共消息)
            mainVerticalBar.setValue(mainVerticalBar.getMaximum());            // 自动调整主窗口的显示信息, 刷新位置
        }

    }

    /**
     * 设置用户名控件,使之总是与服务器同步
     *
    
*/
   
private void handleUsers() {
        usersCombo.removeAllItems();
        usersCombo.addItem(
"所有人");
        String toSelect
= toUser2;
        Iterator
<String> iter = allusers.iterator();
       
while (iter.hasNext()) {
            String one
= iter.next();
            Iterator iter2
= myfriends.iterator();
           
while (iter2.hasNext()) {
               
if (one.equals(iter2.next())) {
                    usersCombo.addItem(
"好友-" + one);
                   
if (one.equals(toUser2)) {
                        toSelect
= "好友-" + one;
                    }
                   
break;
                }
            }
        }
        iter
= allusers.iterator();
        outfor :
       
while (iter.hasNext()) {
            String one
= iter.next();
            Iterator iter2
= myfriends.iterator();
           
while (iter2.hasNext()) {
               
if (one.equals(iter2.next())) {
                   
continue outfor;
                }
            }
           
if (one.equals(myName)) continue;
            usersCombo.addItem(one);
        }
        usersCombo.setSelectedItem(toSelect);
    }


   
public String getIp() {
       
return ip;
    }
   
public void setIp(String ip) {
       
this.ip = ip;
    }
   
public int getPort() {
       
return port;
    }
   
public void setPort(int port) {
       
this.port = port;
    }
   
public Socket getSocket() {
       
return socket;
    }
   
public void setSocket(Socket socket) {
       
this.socket = socket;
    }
   
/**
     * 断开连接
     *
    
*/
   
private void disconnect() {
        close(
false,false);
    }
   
/**
     * 退出程序
     *
    
*/
   
private void close(boolean fromService,boolean toExit) {
       
if (!fromService) {
           
if (theWriter != null) {
                theWriter.println(
"exit");
                theWriter.flush();
            }
        }
        read
= false;
       
if (theWriter != null) {
            theWriter.close();
            theWriter
= null;
        }
       
if (theReader != null) {
           
try {
                theReader.close();
            }
catch (IOException e) {
                e.printStackTrace();
            }
            theReader
= null;
        }
       
if (socket != null) {
           
try {
                socket.close();
            }
catch (IOException e) {
                e.printStackTrace();
            }
            socket
= null;
        }
        connected
= false;
        connectButton.setText(
"连接");
       
if (toExit) {
            System.exit(
0);                    // 退出程序
        }
    }
   
public void keyTyped(KeyEvent e) {

    }
   
public void keyPressed(KeyEvent e) {
       
if (e.getKeyCode() == 10) {            // 响应回车
            send();
        }

    }
   
public void keyReleased(KeyEvent e) {

    }
   
public void focusGained(FocusEvent e) {

    }
   
public void focusLost(FocusEvent e) {
        input.requestFocus();

    }

   
/**
     * 发送文件线程....... 不会影响主程序的运行
    
*/
   
class SendFileThread extends Thread {
        String toUserIp;                       
// 对方IP
        FileInputStream fis = null;                // 文件输入流
        boolean send = true;                    // 发送文件状态标志,如果为FALSE则取消发送
        JDialog dialog;                            // 进度显示窗口
        JProgressBar theBar;                    // 文件传输进度显示控件
        JPanel mainPane;
        JLabel percentLabel
= new JLabel();        // 文件传输百分比标签
        JLabel bytesSendLabel = new JLabel();    // 传输字节标签
        JLabel totalBytesLabel = new JLabel();    // 文件大小标签
        JButton ok;                                // 确定按钮
        JButton cancel;                            // 取消按钮

       
public SendFileThread(String toUserIp) {
           
super();
           
this.toUserIp = toUserIp;
           
try {
                fis
= new FileInputStream(sendFileName);             // 文件输入流新建好了
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            dialog
= new JDialog(ChatClient.this,"文件传输进度");     // 进度显示窗口就绪
            dialog.setLayout(new BorderLayout());
            mainPane
= new JPanel();
            JPanel northPane
= new JPanel(new GridLayout(1,3));
            northPane.add(percentLabel);                           
// 百分比标签
            northPane.add(bytesSendLabel);                            // 已发送字节标签
            northPane.add(totalBytesLabel);                            // 文件总大小标签

            dialog.add(northPane,
"North");                            // 设置窗口北边控件
            JPanel southPane = new JPanel();
            ok
= new JButton("确定");
            ok.addActionListener(
new ActionListener(){
               
public void actionPerformed(ActionEvent ae) {
                    dialog.dispose();
// 如果文件发送完毕,点击确定关闭此窗口
                }
            });
            southPane.add(ok);
            ok.setEnabled(
false);
            cancel
= new JButton("取消");
            cancel.addActionListener(
new ActionListener(){
               
public void actionPerformed(ActionEvent ae) {        // 在发送过程中, 随时可以取消文件发送
                    send = false;
                    alarm(
"您已经取消了文件发送任务!");
                }
            });
            southPane.add(cancel);
            dialog.add(southPane,
"South");
        }

    /**
         * 文件发送线程
        
*/
       
public void run() {
            OutputStream out
= null;
            Socket fileSocket
= null;
           
long fileLeng = -1;
           
long theBytes = 0;
           
try {
               
// 建立SOCKET连接
                fileSocket = new Socket(toUserIp,sendFilePort); // 取得连接
                out = fileSocket.getOutputStream();                    // 获取socket输出流对象,准备往这里写数据
                byte[] buffer = new byte[bufferSize];                // 创建一个缓冲区, 发送文件更快
                int bytesRead = 0;                                    // 准备变量, 保存每次读取的字节数
                fileLeng = new File(sendFileName).length();            // 取得要发送的文件的字节数
                totalBytesLabel.setText("/" + fileLeng + ")字节");    // 设置总字节数标签
                byte[] lengByte = (fileLeng + "").getBytes();        // 把文件长度信息告诉文件接收方.....
                out.write(lengByte.length);
                out.write(lengByte);
                theBar
= new JProgressBar(0,(int)(fileLeng/1024));    // 创建进度条.最大值为文件的总量/1024
                theBar.setValue(0);
                percentLabel.setText((
"0%"));
                dialog.add(theBar);
                WindowTool.doView(dialog,
350,100);                    // 居中显示此进度显示

               
// 开始发送文件
                while (send) {
                    bytesRead
= fis.read(buffer,0,buffer.length);     // 读取文件输入流
                    if (bytesRead <= 0) {                            // 文件发送完毕,则退出循环
                        break;
                    }
                   
// 设置显示信息
                    theBytes += bytesRead;                            // 累计当前已处理的字节数
                    theBar.setValue((int)(theBytes / 1024));        // 处理进度条 使之正确显示
                    bytesSendLabel.setText("(" + theBytes);
                    percentLabel.setText((
int)(((double)theBytes / fileLeng) * 100) + "%");// 显示百分比
                    out.write(buffer,0,bytesRead);                    // 写入SOCKET输出流...........
                }

            }
catch (FileNotFoundException e) {
                e.printStackTrace();
            }
catch (UnknownHostException e) {
                e.printStackTrace();
            }
catch (IOException e) {
                e.printStackTrace();
            }
           
finally {
               
if (out != null) {
                   
try {
                        out.close();                               
// 关闭输出流
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
               
if (fileSocket != null) {
                   
try {
                        fileSocket.close();                           
// 关闭socket对象
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
               
if (fis != null) {
                   
try {
                        fis.close();                               
// 关闭文件输入流对象
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            ok.setEnabled(
true);                                    // 可以点击确定按纽了
            cancel.setEnabled(false);
           
if (theBytes == fileLeng) {
                alarm(
"文件" + sendFileName + "传输完毕!");
            }
           
else if (send){
                alarm(
"文件接收方中断了接收 !");
            }
            sendFileName
= null;
        }
    }
   
/**
     * 文件接收线程类
     * 类似文件发送线程类
     *
@author 刘优
     *
    
*/
   
class RecFileThread extends Thread {
        FileOutputStream fos
= null;                    // 文件输出流
        boolean recv = true;
        JDialog dialog;                                   
// 进度显示窗口
        JProgressBar theBar;                            // 进度条
        JPanel mainPane;
        JLabel percentLabel
= new JLabel();                // 百分比标签
        JLabel bytesRecvLabel = new JLabel();            // 字节数标签
        JLabel totalBytesLabel = new JLabel();            // 总字节数标签
        JButton ok;                                        // 确定按纽
        JButton cancel;                                    // 取消按纽
        File fileToSave;                                // 要接收保存的文件对象

       
public RecFileThread() throws Exception {
            JFileChooser fileChooser
= new JFileChooser();
            fileChooser.showSaveDialog(ChatClient.
this);
            fileToSave
= fileChooser.getSelectedFile();    // 取得要保存的文件对象

           
// 判断写权限
            if (!fileToSave.getParentFile().canWrite() && !fileToSave.canWrite()) {
                alarm(
"不能在目录 [" + fileToSave.getParent() + "] 中创建文件");
               
throw new Exception("没有目录:[" + fileToSave.getParent() + "]的写权限");
            }
           
try {
                fos
= new FileOutputStream(fileToSave);                    // 取得文件输出流
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            dialog
= new JDialog(ChatClient.this,"文件接收进度");        // 进度窗口
            dialog.setLayout(new BorderLayout());
            JPanel northPane
= new JPanel(new GridLayout(1,3));
            northPane.add(percentLabel);
            northPane.add(bytesRecvLabel);
            northPane.add(totalBytesLabel);

            dialog.add(northPane,
"North");
            JPanel southPane
= new JPanel();
            ok
= new JButton("确定");
            ok.addActionListener(
new ActionListener(){
               
public void actionPerformed(ActionEvent ae) {
                    dialog.dispose();
                }
            });
            southPane.add(ok);
            ok.setEnabled(
false);
            cancel
= new JButton("取消");
            cancel.addActionListener(
new ActionListener(){
               
public void actionPerformed(ActionEvent ae) {
                    recv
= false;
                    alarm(
"您已经取消了文件接收任务!");
                }
            });
            southPane.add(cancel);
            dialog.add(southPane,
"South");
        }
       
/**
         * 文件接收线程方法
        
*/
       
public void run() {
            ServerSocket ss
= null;
            Socket fileSocket
= null;
            InputStream in
= null;
           
long fileLeng = 0;
           
long theBytes = 0;
           
try {
               
// 创建服务器端
                ss = new ServerSocket(sendFilePort);
               
// 等待发送方连接
                fileSocket = ss.accept();

                in
= fileSocket.getInputStream();                    // 取得socket输入流
                byte[] buffer = new byte[bufferSize];                // 缓冲区
                int bytesRead = 0;
               
int leng = in.read();
                in.read(buffer,
0,leng);
                String s
= new String(buffer,0,leng);
                fileLeng
= Long.parseLong(s);                        // 先取得文件的总大小
                totalBytesLabel.setText("/" + s + ")字节");
                theBar
= new JProgressBar(0,(int)(fileLeng/1024));
                theBar.setValue(
0);
                percentLabel.setText((
"0%"));
                dialog.add(theBar);
                WindowTool.doView(dialog,
350,100);                    // 居中显示窗口
               
// 开始接收文件
                while (recv) {
                    bytesRead
= in.read(buffer,0,buffer.length);    // 读取SOCKET输入流
                    if (bytesRead <= 0) {
                       
break;
                    }
                   
// 设置显示信息
                    theBytes += bytesRead;
                    theBar.setValue((
int)(theBytes / 1024));        // 设置显示的进度条
                    bytesRecvLabel.setText(" ( " + theBytes);
                    percentLabel.setText((
int)(((double)theBytes / fileLeng) * 100) + "%");//设置百分比标签
                    fos.write(buffer,0,bytesRead);                    // 写入文件输出流
                }

            }
catch (IOException e) {
                e.printStackTrace();
            }
           
finally {
               
// 关闭资源
                if (in != null) {
                   
try {
                        in.close();                                   
//关闭socket输入流对象
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
               
if (fos != null) {
                   
try {
                        fos.close();                               
// 关闭文件输出流对象
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
               
if (fileSocket != null) {
                   
try {
                        fileSocket.close();                           
// 关闭socket对象
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
               
if (ss != null) {
                   
try {
                        ss.close();
// 关闭文件接收服务
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            ok.setEnabled(
true);
            cancel.setEnabled(
false);
           
if (theBytes == fileLeng) {
                alarm(
"文件接收完毕,文件保存为:" + fileToSave.getPath()+ " !");
               
return;
            }
           
else if (recv){
                alarm(
"文件接收被发送方中断 !");
            }
            fileToSave.delete();
// 如果是非正常中断,则把已经接收的片断文件删除..........
            sendFileName = null;
        }
    }

}


package com.chat.main;

import java.io.IOException;
import java.net.*;
import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

import com.chat.client.ChatClient;

/**
* 客户端启动主程序
*
@author 刘优
*
*/
public class ClientMain {
   
public static void main(String[] args) {
       
try {
            String ip
= getMyIp();
           
//System.out.println(ip);
            int port = 8888;
           
if (args.length > 0)
            {
                ip
= args[0];

               
if (args.length > 1)
                {
                   
try {
                        port
= Integer.parseInt(args[1]);
                    }
                   
catch (Exception e) {
                        System.out.println(
"port number : " + args[1] + " is not a integer!");
                    }
                }

            }
            ChatClient client
= new ChatClient(ip,port); // IP 和 端口
        } catch (Exception ee) {
            ee.printStackTrace();
        }
    }
   
private static String getMyIp() throws Exception
    {
        Enumeration allNetInterfaces
= NetworkInterface.getNetworkInterfaces();
        InetAddress ip
= null;
       
while (allNetInterfaces.hasMoreElements())
        {
            NetworkInterface netInterface
= (NetworkInterface)allNetInterfaces.nextElement();
           
//System.out.println(netInterface.getName());
            Enumeration addresses = netInterface.getInetAddresses();
           
while (addresses.hasMoreElements())
            {
                ip
= (InetAddress)addresses.nextElement();
               
if (ip != null && ip instanceof Inet4Address && !(ip.getHostAddress().startsWith("127.")))
                {
                   
//System.out.println("本机的IP = " + ip.getHostAddress());
                    break;
                }
            }
        }
       
return ip.getHostAddress();

    }

}

posted on 2008-07-10 13:19  Pauliuyou  阅读(424)  评论(0编辑  收藏  举报