现在的位置: 首页 > 综合 > 正文

java socket聊天小demo

2012年04月11日 ⁄ 综合 ⁄ 共 5894字 ⁄ 字号 评论关闭

最近需要学习下socket,就顺带做了个聊天的小demo。

基本是抄人家的,我加了个util类,优化了下。

有swing界面的,学生和初学者可以拿走学习下。

http://download.csdn.net/detail/sysmaid/3880649

贴部分代码。

服务器端 线程:

/**
 * 服务线程类
 * @author JingHui
 *
 * create by 2011-11-24 下午1:38:10
 */
class ServerThread extends Thread {
	
	private Socket socket;
	
	public ServerThread(Socket socket){
		this.socket = socket;
	}
	
	public void run(){
		try{
			ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
			
			while(true){
				Vector v = null;
				try{
					v = (Vector)ois.readObject();
				}catch(Exception e){
					e.printStackTrace();
					System.out.println("=======与客户端通信出现错误=======");
				}
				if(v!=null && v.size()>0){
					for(int i=0; i<v.size(); i++){
						String info = (String)v.get(i);
						String key = "";
						if(info.startsWith(ChatUtil.MSG_LOGIN)){
							key = info.substring(7);//获得用户名
							map.put(key, socket);//客户端添加至列表
							ta_info.append(key + " login...\n");
							
							Set<String> set = map.keySet();
							Iterator<String> it = set.iterator();
							while(it.hasNext()){//迭代map,向所有客户端发送登录信息
								String reciveKey = it.next();//表示接收信息的key,即用户名
								Socket s = map.get(reciveKey);
								PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
								pw.println(info);
								pw.flush();
							}
						}else if(info.startsWith(ChatUtil.MSG_EXIT)){//用户退出
							key = info.substring(6);//获得退出用户的key
							ois.close();
							socket.close();
							map.remove(key);
							Set<String> set = map.keySet();
							Iterator<String> it = set.iterator();
							while(it.hasNext()){
								String reciveKey = it.next();
								Socket s = map.get(reciveKey);
								PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
								pw.println(info);
								pw.flush();
							}
							ta_info.append(key + " exit...\n");
							return;//退出线程
						}else if(info.startsWith(ChatUtil.MSG_USERLIST)){//传递当前在线用户列表
							String userList = "";
							Set<String> set = map.keySet();
							Iterator<String> it = set.iterator();
							while(it.hasNext()){
								key = it.next();
								userList += key + ",";
							}
							key = info.substring(10);
							Iterator<String> it2 = set.iterator();
							while(it2.hasNext()){
								String reciveKey = it2.next();
								if(key.equals(reciveKey)){
									Socket s = map.get(reciveKey);
									PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
									pw.println(ChatUtil.MSG_USERLIST + userList);
									pw.flush();
								}
							}
						}else{//正常的消息转发
							String[] infos = ChatUtil.formatInfos(info);
							Set<String> set = map.keySet();
							Iterator<String> it = set.iterator();
							while(it.hasNext()){
								String reciveKey = it.next();
								if(reciveKey.equals(infos[1])){//寻找到接受者
									Socket s = map.get(reciveKey);
									PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
									pw.println(info);//原文转发,客户端进行处理
									pw.flush();
								}
							}
						}//end else
					}//end for
				}//end if v
			}//end while
		}catch(Exception e){
			e.printStackTrace();
			ta_info.append(socket + "退出异常。\n");
		}
	}

}//end class ServerThread

客户端界面:

	/**
	 * 构造函数
	 * 在构造中初始化界面
	 */
	public ChatClientFrame(){
		super();
		this.setTitle("小兔聊天室客户端");
		this.setBounds(100, 100, 385, 288);
		
		final JPanel panel = new JPanel();
		this.getContentPane().add(panel, BorderLayout.SOUTH);
		
		final JLabel label = new JLabel();
		label.setText("输入聊天内容");
		panel.add(label);
		
		tf_send = new JTextField();
		tf_send.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				send();//调用发送方法
			}
		});
		tf_send.setPreferredSize(new Dimension(180, 25));
		panel.add(tf_send);//发送消息区域
		
		final JButton button = new JButton();
		button.setText("发   送");
		button.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				send();
			}
		});
		panel.add(button);//添加发送按钮
		
		final JSplitPane splitPane = new JSplitPane();
		splitPane.setDividerLocation(100);//分隔条的位置
		this.getContentPane().add(splitPane, BorderLayout.CENTER);
		
		final JScrollPane scrollPane = new JScrollPane();
		splitPane.setRightComponent(scrollPane);
		
		ta_info = new JTextArea();
		ta_info.setFont(new Font("", Font.BOLD, 14));
		scrollPane.setViewportView(ta_info);//信息显示区域
		
		//-------显示用户列表 start-------
		final JScrollPane scrollPane1 = new JScrollPane();
		userList = new JList();
		userList.setModel(new DefaultComboBoxModel(new String[] {""}));
		scrollPane1.setViewportView(userList);
		splitPane.setLeftComponent(scrollPane1);
		//-------显示用户列表 end-------
		
		//-------显示用户登录 start-------
		final JPanel panel_1 = new JPanel();
		final JLabel label_1 = new JLabel();
		label_1.setText("用户名称:");
		panel_1.add(label_1);
		
		tf_newUser = new JTextField();
		tf_newUser.setPreferredSize(new Dimension(140, 25));
		panel_1.add(tf_newUser);
		
		final JButton button_1 = new JButton();
		button_1.setText("登   录");
		button_1.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {//进行登录操作
				if(loginFlag){
					JOptionPane.showConfirmDialog(null, "当前用户已登录");
					return;
				}
				String userName = tf_newUser.getText().trim();
				Vector<String> v = new Vector<String>();
				v.add(ChatUtil.fittingLoginMsg(userName));//发送登录信息
				try{
					out.writeObject(v);//发送
					out.flush();
				}catch(Exception e){
					e.printStackTrace();
				}
				tf_newUser.setEnabled(false);//用户名不可修改
				button_1.setVisible(false);//登录按钮隐藏
				loginFlag = true;
				getOnlineUser(userName);//获取在线用户列表
			}
		});
		panel_1.add(button_1);
		
		final JButton button_2 = new JButton();
		button_2.setText("退   出");
		button_2.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				if(!loginFlag){//未登录
					JOptionPane.showMessageDialog(null, "已退出或未登录!");
					return;
				}
				String exitUser = tf_newUser.getText().trim();
				Vector<String> v = new Vector<String>();
				v.add(ChatUtil.fittingExitMsg(exitUser));//退出信息
				try{
					out.writeObject(v);
					out.flush();
				}catch(Exception e){
					e.printStackTrace();
				}
				System.exit(0);
			}
		});
		panel_1.add(button_2);
		this.getContentPane().add(panel_1, BorderLayout.NORTH);
		//-------显示用户登录 end-------
		
		//-------系统托盘 start-------
		if(SystemTray.isSupported()){
			URL url = ChatClientFrame.class.getResource(ChatUtil.LOGO_IMAGE);
			ImageIcon i_con= new ImageIcon(url);
			Image image = i_con.getImage();
			TrayIcon trayIcon = new TrayIcon(image);
			trayIcon.addMouseListener(new MouseAdapter(){
				public void mouseClicked(MouseEvent e) {
					if(e.getClickCount()==2){
						showFrame();//显示界面
					}
				}
			});
			trayIcon.setToolTip("小兔聊天");
			PopupMenu popupMenu = new PopupMenu();
			MenuItem exitMenu = new MenuItem("退出");
			exitMenu.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent arg0) {
					String exitUser = tf_newUser.getText().trim();
					Vector<String> v = new Vector<String>();
					v.add(ChatUtil.fittingExitMsg(exitUser));//退出信息
					try{
						out.writeObject(v);
						out.flush();
						out.close();
						socket.close();
					}catch(Exception e){
						e.printStackTrace();
					}
					System.exit(0);
				}
			});
			popupMenu.add(exitMenu);
			trayIcon.setPopupMenu(popupMenu);
			SystemTray systemTray = SystemTray.getSystemTray();
			try {
				systemTray.add(trayIcon);
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}
		//-------系统托盘 end-------
	}

抱歉!评论已关闭.