配置类:
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();
}
}
}
}