Java实现的聊天室




配置类:

public class Setting {
	public static String SERVER_IP = "127.0.0.1";
	public static int SERVER_PORT = 5250;
	
	public static String COMMAND_LOGIN = "login";
	public static String COMMAND_LOGIN_SUC = "login_suc";
	public static String COMMAND_LOGIN_FAILED = "login_failed";
	public static String COMMAND_LOGOUT = "logout";
	public static String COMMAND_SENDMSG = "sendmsg";
	
	public static String COMMAND_USERLIST = "userlist";
	public static String COMMAND_MSG = "msg";
}


服务端:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

class Server {
	private ServerSocket socket_server;
	private int port;
	private Map<String, Socket> map_client_socket;
	
	public static void main(String args[]){
		try {
			new Server(Setting.SERVER_PORT).start();
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
	}
	
	public Server(int _port) throws IOException {
		this.port = _port;
		map_client_socket = new HashMap<String, Socket>();
	}
	
	public void start() throws IOException {
		try {
		    socket_server = new ServerSocket(port);
		    while(true) {
		    	Socket socket_connection = socket_server.accept();
		    	new ListenService(socket_connection).start();
		    }
		} catch (IOException e) {
			System.out.println("初始化错误");
			throw e;
		}
	}
	
	class ListenService extends Thread {
		private Socket socket;
		private String user_name;
		private boolean logined = false;
		private BufferedReader in = null;
		
		public ListenService(Socket _socket) {
			try {
				socket = _socket;
				in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		public void run() {
			try {
				String command = "";
				while(true) {
					if((command = in.readLine()) != null) {
						if(!logined) {
							if(command.equals(Setting.COMMAND_LOGIN)) {
								user_name = in.readLine();	//读取用户名
								
								//如果用户名存在则发送无法登陆消息并关闭连接
								if(map_client_socket.containsKey(user_name)) {
									sendMsg(socket, Setting.COMMAND_LOGIN_FAILED);
									in.close();
									socket.close();
									break;
								}
								
								//将socket放入map中
								map_client_socket.put(user_name, socket);
								
								String msg = Setting.COMMAND_LOGIN_SUC + "\n" + user_name;
								sendMsgToAll(msg);
								updateUserList();
								logined = true;
							}
						} else {
						 	if(command.equals(Setting.COMMAND_LOGOUT)) {
						 		in.close();
						 		socket.close();
						 		map_client_socket.remove(user_name);
						 		
						 		String msg = Setting.COMMAND_LOGOUT + "\n" + user_name;
						 		sendMsgToAll(msg);
						 		updateUserList();
						 		break;
						 	} else if(command.equals(Setting.COMMAND_SENDMSG)) {
						 		String dest_username = in.readLine();	//读取目标用户名
						 		String msg = Setting.COMMAND_MSG + "\n" 
						 				+ user_name + "\n" //将发送者的用户名发过去
						 				+ in.readLine();
							
						 		if(dest_username.equals("所有人")) {
						 			sendMsgToAll(msg);
						 		} else {
						 			sendMsg(dest_username, msg);
						 		}
						 	}
						}
					}

				}
			} catch (IOException e) {
				e.printStackTrace();
				map_client_socket.remove(user_name);
		 		updateUserList();
			}
		}
		
		public void sendMsg(Socket dest_socket, String message) {
			try {
				PrintWriter out = new PrintWriter(new BufferedWriter(
						new OutputStreamWriter(dest_socket.getOutputStream())),true);
				out.println(message);
				out.flush();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		public void sendMsg(String dest_username, String message) {
			Socket dest_socket = map_client_socket.get(dest_username);
			sendMsg(dest_socket, message);
		}
		
		public void sendMsgToAll(String message) {
			try {
				for(Iterator<Entry<String, Socket>> itor = map_client_socket.entrySet().iterator(); itor.hasNext();) {
					Entry<String, Socket> entry = (Entry<String, Socket>)itor.next();
					
					Socket dest_socket = entry.getValue();
					PrintWriter out = new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(dest_socket.getOutputStream())),true);
					out.println(message);
					out.flush();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		public void updateUserList() {
			String msg = Setting.COMMAND_USERLIST + "\n";
			
			for(Iterator<Entry<String, Socket>> itor = map_client_socket.entrySet().iterator(); itor.hasNext();) {
				Entry<String, Socket> entry = (Entry<String, Socket>)itor.next();
				msg += entry.getKey() + "|";
			}
			
			sendMsgToAll(msg);
		}
	}
}



客户端:

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

public class Client extends JFrame implements ActionListener {
	private static final long serialVersionUID = 2389760719589425440L;
	private String user_name;
	private Socket socket;
	JTextPane text_history;
	Document docs_history;
	JTextArea text_in;
	JButton btn_send;
	JLabel label_destuser;
	JComboBox<String> cbbox_destuser;
	SimpleAttributeSet attrset_cmd = new SimpleAttributeSet();
	SimpleAttributeSet attrset_msg = new SimpleAttributeSet();
	PrintWriter out = null;
	
	public static void main(String args[]) {
		try {
			String name = JOptionPane.showInputDialog("请输入用户名:","user1");
			if(name == null || name.length() == 0)
				return;
			
			Socket socket = new Socket(Setting.SERVER_IP, Setting.SERVER_PORT);
			new Client(name, socket);
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
	
	public Client(String _user_name, Socket _socket) throws IOException {
		super("聊天室 - " + _user_name);
		this.setLayout(null);
		this.setBounds(200, 200, 500, 480);
		this.setResizable(false);
		this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		this.addWindowListener(new CloseHandler());
		
		user_name = _user_name;
		socket = _socket;
		
		text_history = new JTextPane();
		text_history.setBounds(5, 5, 485, 290);
		text_history.setEditable(false);
		JScrollPane scroll_text_history = new JScrollPane(text_history);
		scroll_text_history.setBounds(5, 5, 485, 290);
		this.add(scroll_text_history);
		docs_history = text_history.getDocument();
		
		text_in = new JTextArea();
		text_in.setBounds(5, 305, 485, 110);
		text_in.setLineWrap(true);
		text_in.setEnabled(false);
		JScrollPane scroll_text_in = new JScrollPane(text_in);
		scroll_text_in.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
		scroll_text_in.setBounds(5, 305, 485, 110);
		this.add(scroll_text_in);
		
		btn_send = new JButton("发送(alt+回车)");
		btn_send.setBounds(370, 420, 120, 25);
		btn_send.addActionListener(this);
		btn_send.setEnabled(false);
		btn_send.setMnemonic(KeyEvent.VK_ENTER);
		this.add(btn_send);
		
		label_destuser = new JLabel("发送给:");
		label_destuser.setBounds(215, 420, 50, 25);
		this.add(label_destuser);
		
		cbbox_destuser = new JComboBox<String>();
		cbbox_destuser.setBounds(265, 420, 100, 25);
		this.add(cbbox_destuser);
		
		StyleConstants.setForeground(attrset_cmd, Color.BLUE);
		StyleConstants.setBold(attrset_cmd, true);
		
		StyleConstants.setForeground(attrset_msg, Color.BLACK);
		
		this.setVisible(true);
		out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
		new ListenService(user_name, socket).start();
	}
	
	class CloseHandler extends WindowAdapter {
		public void windowClosing(final WindowEvent ev) {
			try {
				out.println(Setting.COMMAND_LOGOUT);
				out.flush();
				out.close();
				socket.close();
				System.exit(0);
			} catch (IOException e) {
				e.printStackTrace();
				System.exit(0);
			}
		}
	}
	
	@Override
	public void actionPerformed(ActionEvent ev) {
		if(ev.getActionCommand()=="发送(alt+回车)") {
			String dest_user = (String)cbbox_destuser.getSelectedItem();
			if(dest_user == null)
				return;
			
			String msg = text_in.getText();
			insertText("[我] 对 [" + dest_user +  "] 说: (" + getTime() + ")\n", attrset_cmd);
			insertText(msg + "\n", attrset_msg);
			
			out.println(Setting.COMMAND_SENDMSG);
			out.println(dest_user);
			out.println(msg.replaceAll("\\n", "\\\\n"));
			out.flush();
			
			text_in.setText("");
		}
	}

	public void insertText(String str, SimpleAttributeSet attrset) {
		try {
			docs_history.insertString(docs_history.getLength(), str, attrset);
		} catch (BadLocationException ble) {
			System.out.println("BadLocationException:" + ble);
		}
	}
	
	public String getTime() {
		SimpleDateFormat df = new SimpleDateFormat("hh:mm:ss");
		return df.format(new Date());
	}
	
	class ListenService extends Thread {
		private Socket socket;
		private String user_name;
		private BufferedReader in = null;
		private PrintWriter out = null;
		
		public ListenService(String _user_name, Socket _socket) {
			try {
				user_name = _user_name;
				socket = _socket;
				in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		public void run() {
			try {
				String command = "";
				
				//发送登陆命令
				command = Setting.COMMAND_LOGIN + "\n"
						+ user_name + "\n";
				out.print(command);
				out.flush();
				
				while(true) {
					if((command = in.readLine()) != null) {
						if(command.equals(Setting.COMMAND_MSG)) {
							String user_src = in.readLine();
							String msg = in.readLine().replaceAll("\\\\n", "\n");
							if(!user_src.equals(user_name)) {
								insertText("[" + user_src + "] 对 [我] 说: (" + getTime() + ")\n", attrset_cmd);
								insertText(msg + "\n", attrset_msg);
							}
						} else if(command.equals(Setting.COMMAND_USERLIST)) {
							String user_list = in.readLine();
							String user[] = user_list.split("\\|");
							cbbox_destuser.removeAllItems();
							
							cbbox_destuser.addItem("所有人");
							for(int i=0; i<user.length; i++) {
								if(!user[i].equals(user_name))
									cbbox_destuser.addItem(user[i]);
							}
						} else if(command.equals(Setting.COMMAND_LOGIN_SUC)) {
							String user_login = in.readLine();
							insertText("[" + user_login + "] 进入了聊天室. (" + getTime() + ")\n", attrset_cmd);
							text_in.setEnabled(true);
							btn_send.setEnabled(true);
						} else if(command.equals(Setting.COMMAND_LOGIN_FAILED)) {
							insertText(user_name + "登陆失败\n", attrset_cmd);
						} else if(command.equals(Setting.COMMAND_LOGOUT)) {
							String user_logout = in.readLine();
							insertText("[" + user_logout + "] 退出了聊天室. (" + getTime() + ")\n", attrset_cmd);
						}
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值