CentralServer

本文介绍了一个基于Java实现的简单聊天系统,包括中央服务器和客户端的代码细节。该系统支持多个客户端连接,并能实现基本的消息传递功能。服务器端负责管理客户端连接,而客户端能够发送消息给所有在线用户或特定用户。
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JFrame;
import java.awt.Dimension;
import javax.swing.JLabel;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

//import SingleServer.ConnectSocket;

//import SingleServer.RWMessageThread;

public class CentralServer extends JFrame implements ActionListener {

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;
	private JLabel jLabel = null;
	private JTextField jF1 = null;
	private JButton jB1 = null;
	private JLabel jLabel1 = null;
	private JList jL1 = null;
	private JScrollPane jScrollPane = null;
	private JLabel jLabel2 = null;
	private JTextArea jT1 = null;
	private JScrollPane jScrollPane1 = null;
	private JLabel jLabel3 = null;
	private JTextArea jT2 = null;
	private JScrollPane jScrollPane2 = null;
	
	ServerSocket server;
	Vector clients= new Vector();//在线客户读写 线程对象
	ConnectSocket s;

	//检测客户是否重名 的 方法
	public boolean checkName(Client newc){
		int num = clients.size();
		for(int i=0; i<num; i++){
			Client c=(Client)clients.elementAt(i);
			if((c!=newc)  && (c.name.equals(newc.name)))
				return false;//
		}
		
		return true;
	}
	
	public void disconnect(Client c){
		c.Send("QUIT");
		clients.removeElement(c);
		jT1.append(c.name+"断开连接!\n");
	}
	
	public void sendClients(String msg){
		for(int i=0; i<clients.size(); i++){
			Client c=(Client)clients.elementAt(i);
			c.Send(msg);
		}
	}
	
	public void sendClientsExcept(String msg, Client srcClient){
		for(int i=0; i<clients.size(); i++){
			Client c=(Client)clients.elementAt(i);
			if(c != srcClient)
				c.Send(msg);
		}
	}
	
	public void notifyRoom(){
		String str = "PEOPLE";
		
		Vector inames = new Vector();
		
		for(int i=0; i<clients.size(); i++){
			Client c=(Client)clients.elementAt(i);
			str+=":"+c.name;
			inames.addElement(c.name);
		}
		jL1.setListData(inames);//更新到 界面
		sendClients(str);
	}
	
	class ConnectSocket extends Thread{
		Socket socket;
		public void run(){
			while(true){
				try {
					socket = server.accept();
					//socket: 服务台 指派 socket(相当于服务专员)为
					//刚连接进来的客户机服务
				} catch (IOException e) {
					// TODO Auto-generated catch block
					jT1.append("用户连接异常!\n");
				}
				
				//socket(相当于服务专员)开展它的服务工作:读写客户机信息
				Client rw = new Client(socket);//必须在这条语句执行时,获知客户机名称
				//如果是重名客户连接进来,我们不要 启动收发工作
				if(checkName(rw))
				{
					clients.addElement(rw);
					rw.start();
					//更新 客户机列表
					notifyRoom();
				}
				else
				{//发生了重名
					//rw.Send("QUIT");
					//rw.stop();
					disconnect(rw);
				}
			}
		}
	}
	
	class Client extends Thread{
		BufferedReader cin;
		PrintStream cout;
		Socket sk;
		String name;//
		
		public void Send(String str){
			cout.println(str);
			cout.flush();//不缓冲,理解执行
		}
		
		public Client(Socket socket)
		{
			this.sk = socket;
			
			try {
				cin = new BufferedReader(new InputStreamReader(sk.getInputStream()));
				cout  = new PrintStream(sk.getOutputStream());
				
				String str = cin.readLine();
				//str 的格式 :"PEOPLE:老小孩"
				StringTokenizer st = new StringTokenizer(str, ":");
				String keyword = st.nextToken();
				if(!keyword.equalsIgnoreCase("PEOPLE"))
				{
					//不是自己的客户端
					Send("QUIT");
					return;
				}
				else{
					//是自己的客户端来连接 ,读取 客户机 名称
					name = st.nextToken();
					jT1.append(name+"已经连接!\n");
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				//e.printStackTrace();
				jT1.append("创建客户读写对象时 产生了异常!\n");
			}
			
		}
		
		public void run(){
			String str = null;
			
			//boolean bFirstRead = true;
			
			while(true){
				
				try {
					str = cin.readLine();
					
					//第二条及以后信息的解析
						StringTokenizer st = new StringTokenizer(str, ":");
						String keyword = st.nextToken();
						if(keyword.equals("MSG")){
							//将str 直接 群体  转发 
							//sendClients(str);
							sendClientsExcept(str, this);//
						}
						else if(keyword.equals("QUIT"))
						{
							//Send("QUIT");
							disconnect(this);
							//更新在线列表,并且 群发给所有客户机
							notifyRoom();
							//读写 客户的该线程 可以 停止了
							break;
						}
									
					
					/*if(!str.equals("QUIT")){
						cout.println("服务器反馈信息."+str);
					}	*/
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				/*
				//应用层协议
				if(str.equals("QUIT"))
				{
					cout.println("QUIT");
					try {
						sk.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					break;
				}	*/
				
				jT2.append(str+"\n");
			}
		}
	}
	
	/**
	 * This is the default constructor
	 */
	public CentralServer() {
		super();
		initialize();
	}
	
	public static void main(String[] args){
		CentralServer w1 = new CentralServer();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(628, 276);
		this.setContentPane(getJContentPane());
		
		this.jB1.addActionListener(this);
		this.setTitle("即时通讯系统-中央服务器");
		
		this.setVisible(true);//
		this.addWindowListener(new java.awt.event.WindowAdapter() {
			public void windowClosing(java.awt.event.WindowEvent e) {
				//System.out.println("windowClosing()"); // TODO Auto-generated Event stub windowClosing()
				if(s!=null)
				{
					if(s.isAlive())
					{
						s.stop();
					}
				}
				
				if(server !=null){
					try {
						server.close();
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
			}
		});
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jLabel3 = new JLabel();
			jLabel3.setBounds(new Rectangle(286, 41, 119, 18));
			jLabel3.setText("聊天信息");
			jLabel2 = new JLabel();
			jLabel2.setBounds(new Rectangle(132, 41, 132, 18));
			jLabel2.setText("连接信息及系统信息");
			jLabel1 = new JLabel();
			jLabel1.setBounds(new Rectangle(7, 41, 91, 18));
			jLabel1.setText("在线客户列表");
			jLabel = new JLabel();
			jLabel.setBounds(new Rectangle(7, 7, 78, 18));
			jLabel.setText("监听端口");
			jContentPane = new JPanel();
			jContentPane.setLayout(null);
			jContentPane.add(jLabel, null);
			jContentPane.add(getJF1(), null);
			jContentPane.add(getJB1(), null);
			jContentPane.add(jLabel1, null);
			jContentPane.add(getJScrollPane(), null);
			jContentPane.add(jLabel2, null);
			jContentPane.add(getJScrollPane1(), null);
			jContentPane.add(jLabel3, null);
			jContentPane.add(getJScrollPane2(), null);
		}
		return jContentPane;
	}

	/**
	 * This method initializes jF1	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getJF1() {
		if (jF1 == null) {
			jF1 = new JTextField();
			jF1.setBounds(new Rectangle(92, 7, 161, 22));
			jF1.setText("6598");
		}
		return jF1;
	}

	/**
	 * This method initializes jB1	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJB1() {
		if (jB1 == null) {
			jB1 = new JButton();
			jB1.setBounds(new Rectangle(286, 7, 225, 21));
			jB1.setText("开始监听");
		}
		return jB1;
	}

	/**
	 * This method initializes jL1	
	 * 	
	 * @return javax.swing.JList	
	 */
	private JList getJL1() {
		if (jL1 == null) {
			jL1 = new JList();
		}
		return jL1;
	}

	/**
	 * This method initializes jScrollPane	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getJScrollPane() {
		if (jScrollPane == null) {
			jScrollPane = new JScrollPane();
			jScrollPane.setBounds(new Rectangle(7, 64, 112, 166));
			jScrollPane.setViewportView(getJL1());
		}
		return jScrollPane;
	}

	/**
	 * This method initializes jT1	
	 * 	
	 * @return javax.swing.JTextArea	
	 */
	private JTextArea getJT1() {
		if (jT1 == null) {
			jT1 = new JTextArea();
		}
		return jT1;
	}

	/**
	 * This method initializes jScrollPane1	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getJScrollPane1() {
		if (jScrollPane1 == null) {
			jScrollPane1 = new JScrollPane();
			jScrollPane1.setBounds(new Rectangle(131, 64, 137, 167));
			jScrollPane1.setViewportView(getJT1());
		}
		return jScrollPane1;
	}

	/**
	 * This method initializes jT2	
	 * 	
	 * @return javax.swing.JTextArea	
	 */
	private JTextArea getJT2() {
		if (jT2 == null) {
			jT2 = new JTextArea();
		}
		return jT2;
	}

	/**
	 * This method initializes jScrollPane2	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getJScrollPane2() {
		if (jScrollPane2 == null) {
			jScrollPane2 = new JScrollPane();
			jScrollPane2.setBounds(new Rectangle(280, 64, 332, 162));
			jScrollPane2.setViewportView(getJT2());
		}
		return jScrollPane2;
	}

	@Override
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
		try {
			server = new ServerSocket(Integer.parseInt(jF1.getText()));
			jT1.append("打开端口成功!\n");
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			jT1.append("服务器端口打开错误!\n");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			jT1.append("服务器端口打开错误!\n");
		}
		
		if(server != null)
		{
			s = new ConnectSocket();
			s.start();
		}
		
	}

}  //  @jve:decl-index=0:visual-constraint="10,10"



import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JFrame;
import java.awt.Dimension;
import javax.swing.JLabel;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.swing.ButtonGroup;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JList;
import javax.swing.JTextArea;
import javax.swing.JRadioButton;

//import SingleClient.ReadMessageThread;

public class multiClients extends JFrame implements ActionListener {

    private static final long serialVersionUID = 1L;
    private JPanel jContentPane = null;
    private JLabel jLabel = null;
    private JTextField jF1 = null;
    private JLabel jLabel1 = null;
    private JTextField jF2 = null;
    private JLabel jLabel2 = null;
    private JTextField jF3 = null;
    private JButton jB1 = null;
    private JTextField jF4 = null;
    private JButton jB2 = null;
    private JButton jB3 = null;
    private JScrollPane jScrollPane = null;
    private JList jL1 = null;
    private JScrollPane jScrollPane1 = null;
    private JTextArea jT1 = null;
    
    Socket skt=null;
    BufferedReader cin=null;
    PrintStream cout=null;
    String name="";
    private JRadioButton jR1 = null;
    private JRadioButton jR2 = null;

    /**
     * This is the default constructor
     */
    public multiClients() {
        super();
        initialize();
    }

    /**
     * This method initializes this
     * 
     * @return void
     */
    private void initialize() {
        this.setSize(696, 277);
        this.setContentPane(getJContentPane());
        
        this.jB1.addActionListener(this);
        this.jB2.addActionListener(this);
        this.jB3.addActionListener(this);
        
        this.jR1.setSelected(true);
        ButtonGroup bg = new ButtonGroup();
        bg.add(jR1);
        bg.add(jR2);
        
        this.setTitle("即时通讯系统-客户端");
        
        this.setVisible(true);
        this.addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent e) {
                //System.out.println("windowClosing()"); // TODO Auto-generated Event stub windowClosing()
                if(skt !=null)
                {
                    try {
                        skt.close();
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }
            }
        });
    }
    
    class ReadMessageThread extends Thread{
        public void run(){
            String str = null;
            
            while(true){
                
                try {
                    str = cin.readLine();
                    
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                
                StringTokenizer st = new StringTokenizer(str, ":");
                String keyword = st.nextToken();
                
                //应用层协议
                if(keyword.equals("QUIT"))
                {
                    //cout.println("QUIT");
                    try {
                        skt.close();
                        jT1.append("服务器批准了本客户机断开连接,本客户机先处于离线状态!\n");
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    break;
                }
                else if(keyword.equals("PEOPLE")){
                    Vector inames = new Vector();
                    while(st.hasMoreTokens())
                        inames.addElement(st.nextToken());
                    jL1.setListData(inames);
                    
                }
                else if(keyword.equals("MSG")){
                    String str1 = st.nextToken("\0");
                    str1 = str1.substring(1);//取索引从1 到 最后  的所有字符,-->str1
                    jT1.append(str1+"\n");
                }
                
                //jT1.append("server应答:"+str+"\n");
            }
        }
    }
    
    /**
     * This method initializes jR1    
     *     
     * @return javax.swing.JRadioButton    
     */
    private JRadioButton getJR1() {
        if (jR1 == null) {
            jR1 = new JRadioButton();
            jR1.setBounds(new Rectangle(347, 32, 93, 21));
            jR1.setText("所有客户机");
        }
        return jR1;
    }

    /**
     * This method initializes jR2    
     *     
     * @return javax.swing.JRadioButton    
     */
    private JRadioButton getJR2() {
        if (jR2 == null) {
            jR2 = new JRadioButton();
            jR2.setBounds(new Rectangle(349, 52, 125, 21));
            jR2.setText("特定客户机");
        }
        return jR2;
    }

    public static void main(String[] args){
        multiClients w1 = new multiClients();
    }

    /**
     * This method initializes jContentPane
     * 
     * @return javax.swing.JPanel
     */
    private JPanel getJContentPane() {
        if (jContentPane == null) {
            jLabel2 = new JLabel();
            jLabel2.setBounds(new Rectangle(336, 9, 70, 17));
            jLabel2.setText("客户机名称");
            jLabel1 = new JLabel();
            jLabel1.setBounds(new Rectangle(180, 10, 56, 18));
            jLabel1.setText("端口");
            jLabel = new JLabel();
            jLabel.setBounds(new Rectangle(4, 8, 56, 18));
            jLabel.setText("服务器IP");
            jContentPane = new JPanel();
            jContentPane.setLayout(null);
            jContentPane.add(jLabel, null);
            jContentPane.add(getJF1(), null);
            jContentPane.add(jLabel1, null);
            jContentPane.add(getJF2(), null);
            jContentPane.add(jLabel2, null);
            jContentPane.add(getJF3(), null);
            jContentPane.add(getJB1(), null);
            jContentPane.add(getJF4(), null);
            jContentPane.add(getJB2(), null);
            jContentPane.add(getJB3(), null);
            jContentPane.add(getJScrollPane(), null);
            jContentPane.add(getJScrollPane1(), null);
            jContentPane.add(getJR1(), null);
            jContentPane.add(getJR2(), null);
        }
        return jContentPane;
    }

    /**
     * This method initializes jF1    
     *     
     * @return javax.swing.JTextField    
     */
    private JTextField getJF1() {
        if (jF1 == null) {
            jF1 = new JTextField();
            jF1.setBounds(new Rectangle(69, 7, 102, 22));
            jF1.setText("127.0.0.1");
        }
        return jF1;
    }

    /**
     * This method initializes jF2    
     *     
     * @return javax.swing.JTextField    
     */
    private JTextField getJF2() {
        if (jF2 == null) {
            jF2 = new JTextField();
            jF2.setBounds(new Rectangle(245, 6, 84, 24));
            jF2.setText("6598");
        }
        return jF2;
    }

    /**
     * This method initializes jF3    
     *     
     * @return javax.swing.JTextField    
     */
    private JTextField getJF3() {
        if (jF3 == null) {
            jF3 = new JTextField();
            jF3.setBounds(new Rectangle(417, 9, 82, 24));
            jF3.setText("黑山老妖");
        }
        return jF3;
    }

    /**
     * This method initializes jB1    
     *     
     * @return javax.swing.JButton    
     */
    private JButton getJB1() {
        if (jB1 == null) {
            jB1 = new JButton();
            jB1.setBounds(new Rectangle(520, 9, 155, 27));
            jB1.setText("连接服务器");
        }
        return jB1;
    }

    /**
     * This method initializes jF4    
     *     
     * @return javax.swing.JTextField    
     */
    private JTextField getJF4() {
        if (jF4 == null) {
            jF4 = new JTextField();
            jF4.setBounds(new Rectangle(6, 41, 327, 32));
        }
        return jF4;
    }

    /**
     * This method initializes jB2    
     *     
     * @return javax.swing.JButton    
     */
    private JButton getJB2() {
        if (jB2 == null) {
            jB2 = new JButton();
            jB2.setBounds(new Rectangle(492, 43, 89, 28));
            jB2.setText("发送信息");
        }
        return jB2;
    }

    /**
     * This method initializes jB3    
     *     
     * @return javax.swing.JButton    
     */
    private JButton getJB3() {
        if (jB3 == null) {
            jB3 = new JButton();
            jB3.setBounds(new Rectangle(587, 44, 87, 28));
            jB3.setText("断开连接");
        }
        return jB3;
    }

    /**
     * This method initializes jScrollPane    
     *     
     * @return javax.swing.JScrollPane    
     */
    private JScrollPane getJScrollPane() {
        if (jScrollPane == null) {
            jScrollPane = new JScrollPane();
            jScrollPane.setBounds(new Rectangle(11, 79, 106, 153));
            jScrollPane.setViewportView(getJL1());
        }
        return jScrollPane;
    }

    /**
     * This method initializes jL1    
     *     
     * @return javax.swing.JList    
     */
    private JList getJL1() {
        if (jL1 == null) {
            jL1 = new JList();
        }
        return jL1;
    }

    /**
     * This method initializes jScrollPane1    
     *     
     * @return javax.swing.JScrollPane    
     */
    private JScrollPane getJScrollPane1() {
        if (jScrollPane1 == null) {
            jScrollPane1 = new JScrollPane();
            jScrollPane1.setBounds(new Rectangle(131, 83, 545, 149));
            jScrollPane1.setViewportView(getJT1());
        }
        return jScrollPane1;
    }

    /**
     * This method initializes jT1    
     *     
     * @return javax.swing.JTextArea    
     */
    private JTextArea getJT1() {
        if (jT1 == null) {
            jT1 = new JTextArea();
        }
        return jT1;
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub
        if(arg0.getSource() == jB1)
        {
            try {
                InetAddress ip=InetAddress.getByName(jF1.getText());
                int port = Integer.parseInt(jF2.getText());
                skt = new Socket(ip, port);
                jT1.append("与聊天服务器连接......\n");
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                //e.printStackTrace();
                jT1.append("服务器连接失败!\n");
            }
            
            if(skt != null){
                try {
                    name = jF3.getText().trim();//忽略空格
                    cin = new BufferedReader(new InputStreamReader(skt.getInputStream()));
                    cout  = new PrintStream(skt.getOutputStream());
                    
                    String str = "PEOPLE:"+name;
                    cout.println(str);
                    jT1.append("To Server:"+str+"\n");
                    
                    ReadMessageThread rt = new ReadMessageThread();
                    rt.start();
                    
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        
        if(arg0.getSource() == jB2){//发送信息
            String str = jF4.getText();
            str="MSG:"+name+":"+str;
            cout.println(str);
            jT1.append("To Server:"+str+"\n");
        }
        
        if(arg0.getSource()  == jB3){
            String str = "QUIT";
            cout.println(str);
            jT1.append("本客户机请求断开连接!\n");
        }
    }

}  //  @jve:decl-index=0:visual-constraint="10,10"

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值