Server
package org.zbq.server;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import org.zbq.util.CharUtil;
import org.zbq.util.XMLUtil;
public class Server {
private JFrame frame;
private JLabel lab_serverState;
private JLabel lab_state;
private JLabel lab_port;
private JTextField field_port;
private JTextArea area;
private JButton but_startServer;
private Map<String, ServerMessageThread> map = new HashMap<String, ServerMessageThread>();
public JTextArea getArea() {
return area;
}
public void setArea(JTextArea area) {
this.area = area;
}
public JButton getBut_startServer() {
return but_startServer;
}
public void setBut_startServer(JButton but_startServer) {
this.but_startServer = but_startServer;
}
public JLabel getLab_state() {
return lab_state;
}
public void setLab_state(JLabel lab_state) {
this.lab_state = lab_state;
}
public Map<String, ServerMessageThread> getMap() {
return map;
}
public void setMap(Map<String, ServerMessageThread> map) {
this.map = map;
}
public JTextField getField_port() {
return field_port;
}
public void setField_port(JTextField field_port) {
this.field_port = field_port;
}
public Server() {
frame = new JFrame("Server");
area = new JTextArea(22, 33);
lab_serverState = new JLabel("Server State:");
lab_state = new JLabel("Stop");
lab_port = new JLabel("Port:");
but_startServer = new JButton("Start");
field_port = new JTextField(15);
area.setEditable(false);
lab_state.setForeground(Color.red);
int x = (int) (Toolkit.getDefaultToolkit().getScreenSize().width * 0.4);
int y = (int) (Toolkit.getDefaultToolkit().getScreenSize().height * 0.2);
addListener();
frame.setBounds(x, y, 400, 560);
frame.add(getTopContainer(), BorderLayout.NORTH);
frame.add(getCenterContainer(), BorderLayout.CENTER);
frame.setVisible(true);
frame.setResizable(false);
}
private Container getTopContainer() {
JPanel pan = new JPanel(new GridLayout(2, 1));
JPanel pan1 = new JPanel(new FlowLayout(FlowLayout.CENTER, 25, 1));
JPanel pan2 = new JPanel(new FlowLayout(FlowLayout.CENTER, 15, 1));
pan1.add(lab_serverState);
pan1.add(lab_state);
pan2.add(lab_port);
pan2.add(field_port);
pan2.add(but_startServer);
pan.add(pan1);
pan.add(pan2);
pan.setBorder(BorderFactory.createTitledBorder("Server Information"));
return pan;
}
private Container getCenterContainer() {
JPanel pan = new JPanel();
pan.add(new JScrollPane(area));
pan.setBorder(BorderFactory.createTitledBorder("Online User List"));
return pan;
}
private void addListener() {
/* start button add listener */
but_startServer.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
execute(e);
}
});
/* Close the window add listener */
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
try {
Collection<ServerMessageThread> cols = map.values();
String messageXML = XMLUtil.constructCloseServerWindowXML();
for (ServerMessageThread smt : cols) {
smt.sendMessage(messageXML);
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
System.exit(0);
}
}
});
}
private boolean execute(ActionEvent e) {
String hostPort = field_port.getText();
if (CharUtil.isEmpty(hostPort)) {
JOptionPane.showMessageDialog(frame,
"The port number can't for empty! ");
field_port.requestFocus();
return false;
}
if (!CharUtil.isNumber(hostPort)) {
JOptionPane.showMessageDialog(frame, "Port must is a number!",
"Error", JOptionPane.YES_OPTION);
field_port.requestFocus();
return false;
}
if (!CharUtil.isPortCorrect(hostPort)) {
JOptionPane.showMessageDialog(frame, "Port must 1024-65535",
"Error", JOptionPane.YES_OPTION);
field_port.requestFocus();
return false;
}
try{
int port = Integer.parseInt(hostPort);
new ServerConnection(this, port).start();
}catch (Exception ex) {
ex.printStackTrace();
return false;
}
return true;
}
public static void main(String[] args) {
new Server();
}
}
ServerConnectThread
package org.zbq.server;
import java.awt.Color;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JOptionPane;
import org.zbq.util.XMLUtil;
public class ServerConnection extends Thread {
private Server server;
private ServerSocket serverSocket;
public ServerConnection(Server server, int port) {
this.server = server;
try {
this.serverSocket = new ServerSocket(port);
this.server.getLab_state().setText("Running");
this.server.getLab_state().setForeground(Color.GREEN);
this.server.getBut_startServer().setEnabled(false);
this.server.getField_port().setEditable(false);
} catch (IOException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "The port number occupied", "ERROR", JOptionPane.ERROR_MESSAGE);
}
}
@Override
public void run() {
while(true){
try {
Socket socket = this.serverSocket.accept();
InputStream input = socket.getInputStream();
OutputStream output = socket.getOutputStream();
byte[] buf = new byte[5000];
int len = input.read(buf);
String loginXML = new String(buf, 0, len);
String userName = XMLUtil.extractUsername(loginXML);
boolean isLogin = false;
String loginResult = null;
/*judge userName is repeated*/
if(this.server.getMap().containsKey(userName)){
loginResult = "failure";
}else{
loginResult = "success";
isLogin = true;
}
String xml = XMLUtil.constructLoginResultXML(loginResult);
output.write(xml.getBytes());
/*client login success*/
if(isLogin){
ServerMessageThread serverMessageThread = new ServerMessageThread(this.server, socket);
/*put username and message thread to map*/
this.server.getMap().put(userName, serverMessageThread);
/*update the user list*/
serverMessageThread.updateUserList();
serverMessageThread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ServerMessageThread
package org.zbq.server;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Calendar;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import org.zbq.util.CharUtil;
import org.zbq.util.XMLUtil;
public class ServerMessageThread extends Thread {
private Server server;
private InputStream input;
private OutputStream output;
public ServerMessageThread(Server server, Socket socket) {
this.server = server;
try {
this.input = socket.getInputStream();
this.output = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*
* send messageXML to client
*/
public void sendMessage(String messageXML) {
try {
output.write(messageXML.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* update the server user list send to all clients new user list
*/
public void updateUserList() {
/* get users set */
Set<String> users = this.server.getMap().keySet();
String xml = XMLUtil.constructUserList(users);
StringBuffer buff = new StringBuffer();
for (String user : users) {
buff.append(user + "\n");
}
/* update server user list */
this.server.getArea().setText(buff.toString());
Collection<ServerMessageThread> cols = this.server.getMap().values();
/* send new user list to all clients */
for (ServerMessageThread smt : cols) {
smt.sendMessage(xml);
}
}
@Override
public void run() {
while(true){
byte[] buf = new byte[5000];
try {
int len = this.input.read(buf);
String xml = new String(buf, 0, len);
int type = Integer.parseInt(XMLUtil.extractType(xml));
// File file = new File("./content.txt");
// if(!file.exists()){
// file.createNewFile();
// }
// FileOutputStream out = new FileOutputStream(file, true);
// out.write(xml.getBytes());
// out.close();
if(CharUtil.CLIENT_MESSAGE == type){
/*get user name*/
String userName = XMLUtil.extractUsername(xml);
/*get content*/
String content = XMLUtil.extractContent(xml);
String message = userName + " "
+ Calendar.getInstance().get(Calendar.HOUR_OF_DAY) + ":"
+ Calendar.getInstance().get(Calendar.MINUTE) + ":"
+ Calendar.getInstance().get(Calendar.SECOND) + "\n "
+ content;
String messageXML = XMLUtil.constructServerMessageXML(message);
Map<String, ServerMessageThread> map = this.server.getMap();
Collection<ServerMessageThread> cols = map.values();
/*send all clients chat message*/
for(ServerMessageThread smt : cols){
smt.sendMessage(messageXML);
}
/*when client close the window*/
}else if(CharUtil.CLOSE_CLIENT_WINDOW == type){
String userName = XMLUtil.extractUsername(xml);
ServerMessageThread smt = this.server.getMap().get(userName);
String confirmationXML = XMLUtil.constructCloseClientWindowConfirmationXML();
smt.sendMessage(confirmationXML);
this.server.getMap().remove(userName);
this.updateUserList();
this.input.close();
this.output.close();
/*over this thread*/
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ClientLogin
package org.zbq.client;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import org.zbq.util.CharUtil;
public class ClientLogin {
private JFrame frame;
private JLabel lab_userName;
private JLabel lab_serverAddress;
private JLabel lab_port;
private JTextField field_userName;
private JTextField field_serverAddress;
private JTextField field_port;
private JButton but_login;
private JButton but_reset;
public ClientLogin(){
this.frame = new JFrame("Chart room Login");
this.lab_userName = new JLabel("User Name:");
this.lab_serverAddress = new JLabel("Server Address:");
this.lab_port = new JLabel("Port:");
this.field_userName = new JTextField(15);
this.field_serverAddress = new JTextField(15);
this.field_port = new JTextField(15);
this.but_login = new JButton("Login");
this.but_reset = new JButton("Reset");
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
int x = (int) (dimension.getWidth()*0.4);
int y = (int) (dimension.getHeight()*0.3);
this.frame.setBounds(x, y, 320, 245);
this.frame.setResizable(false);
frame.add(getCenterContainer(), BorderLayout.CENTER);
frame.add(getBottonContainer(), BorderLayout.SOUTH);
addListener();
this.frame.setVisible(true);
this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
/**/
private Container getCenterContainer(){
JPanel pan = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 15));
lab_userName.setPreferredSize(new Dimension(100, 25));
field_userName.setPreferredSize(new Dimension(80, 25));
lab_serverAddress.setPreferredSize(new Dimension(100, 25));
field_serverAddress.setPreferredSize(new Dimension(80, 25));
lab_port.setPreferredSize(new Dimension(100, 25));
field_port.setPreferredSize(new Dimension(80, 25));
pan.add(lab_userName);
pan.add(field_userName);
pan.add(lab_serverAddress);
pan.add(field_serverAddress);
pan.add(lab_port);
pan.add(field_port);
pan.setBorder(BorderFactory.createTitledBorder(new TitledBorder("User Login")));
return pan;
}
private Container getBottonContainer(){
JPanel pan = new JPanel();
but_login.setPreferredSize(new Dimension(100, 30));
but_reset.setPreferredSize(new Dimension(100, 30));
pan.add(but_login);
pan.add(but_reset);
return pan;
}
public JFrame getFrame() {
return frame;
}
public void setFrame(JFrame frame) {
this.frame = frame;
}
private void addListener(){
but_reset.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
field_userName.setText("");
field_serverAddress.setText("");
field_port.setText("");
}
});
but_login.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
login(e);
}
});
}
private void login(ActionEvent e){
String userName = field_userName.getText();
String portStr = field_port.getText();
String serverAddr = field_serverAddress.getText();
if(CharUtil.isEmpty(userName)){
JOptionPane.showMessageDialog(frame, "User name can't for empty!", "Error", JOptionPane.YES_OPTION);
field_userName.requestFocus();
return;
}
if(CharUtil.isEmpty(portStr)){
JOptionPane.showMessageDialog(frame, "Port can't for empty!", "Error", JOptionPane.YES_OPTION);
field_port.requestFocus();
return;
}
if(CharUtil.isEmpty(serverAddr)){
JOptionPane.showMessageDialog(frame, "Server Address can't for empty!", "Error", JOptionPane.YES_OPTION);
field_serverAddress.requestFocus();
return;
}
if(!CharUtil.isNumber(portStr)){
JOptionPane.showMessageDialog(frame, "Port must is a number!", "Error", JOptionPane.YES_OPTION);
field_port.requestFocus();
return;
}
if(!CharUtil.isPortCorrect(portStr)){
JOptionPane.showMessageDialog(frame, "Port must 1024-65535!", "Error", JOptionPane.YES_OPTION);
field_port.requestFocus();
return;
}
int port = Integer.parseInt(portStr);
ClientConnection clientConnection = new ClientConnection(this, serverAddr, port, userName);
if(clientConnection.login()){
clientConnection.start();
}else{
JOptionPane.showMessageDialog(null, "userName reduplicate", "ERROR", JOptionPane.YES_OPTION);
}
}
public static void main(String[] args) {
new ClientLogin();
}
}
ChatRoom
package org.zbq.client;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Toolkit;
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.File;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class ChatRoom {
private ClientConnection clientConnection;
private JFrame frame;
private JTextArea area_chatRoomInfo;
private JTextArea area_onlineUserList;
private JTextArea area_inputInfo;
private JButton but_send;
private JButton but_clear;
public JTextArea getArea_chatRoomInfo() {
return area_chatRoomInfo;
}
public void setArea_chatRoomInfo(JTextArea area_chatRoomInfo) {
this.area_chatRoomInfo = area_chatRoomInfo;
}
public JTextArea getArea_onlineUserList() {
return area_onlineUserList;
}
public void setArea_onlineUserList(JTextArea area_onlineUserList) {
this.area_onlineUserList = area_onlineUserList;
}
public JTextArea getArea_inputInfo() {
return area_inputInfo;
}
public void setArea_inputInfo(JTextArea area_inputInfo) {
this.area_inputInfo = area_inputInfo;
}
public ChatRoom(ClientConnection clientConnection, String title){
this.clientConnection = clientConnection;
frame = new JFrame(title);
area_chatRoomInfo = new JTextArea(10, 15);
area_onlineUserList = new JTextArea(25, 10);
area_inputInfo = new JTextArea(5, 5);
but_send = new JButton("Send(S)");
but_clear = new JButton("Clear");
Color color = new Color(255, 255, 255);
frame.setBackground(color);
area_inputInfo.setLineWrap(true);
area_inputInfo.setFont(new Font(area_inputInfo.getText(), Font.BOLD, 16));
area_chatRoomInfo.setFont(new Font(area_chatRoomInfo.getText(), Font.TYPE1_FONT, 16));
area_onlineUserList.setEditable(false);
int x = (int) (Toolkit.getDefaultToolkit().getScreenSize().width*0.4);
int y = (int) (Toolkit.getDefaultToolkit().getScreenSize().height*0.2);
frame.setBounds(x, y, 600, 530);
frame.add(getLeftContainer(), BorderLayout.CENTER);
frame.add(getRightContainer(), BorderLayout.EAST);
addListener();
File imageFileDir = new File("images");
File[] imageFiles = imageFileDir.listFiles();
int size = imageFiles.length;
// System.out.println(size);
int point =(int) (Math.random()*size);
// ImageIcon icon = new ImageIcon("./images/bg.png");
ImageIcon icon = new ImageIcon(imageFiles[point].getAbsolutePath());
JLabel imgLabel = new JLabel(icon);
frame.getLayeredPane().add(imgLabel, new Integer(Integer.MIN_VALUE));
imgLabel.setBounds(0, 0, icon.getIconWidth(), icon.getIconHeight());
Container cont = frame.getContentPane();
((JPanel)cont).setOpaque(false);
area_chatRoomInfo.setOpaque(false);
area_inputInfo.setOpaque(false);
area_onlineUserList.setOpaque(false);
frame.setVisible(true);
}
private Container getLeftContainer(){
JPanel pan = new JPanel(new BorderLayout());
JPanel pan1 = new JPanel(new BorderLayout());
JPanel pan2 = new JPanel(new BorderLayout());
JPanel pan3 = new JPanel(new GridLayout(1, 2));
pan3.add(but_send, BorderLayout.EAST);
pan3.add(but_clear, BorderLayout.WEST);
pan2.add(new JLabel(""), BorderLayout.CENTER);
pan2.add(pan3, BorderLayout.EAST);
pan1.add(pan2, BorderLayout.SOUTH);
JScrollPane scr = new JScrollPane(area_inputInfo);
scr.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
pan1.add(scr, BorderLayout.CENTER);
JScrollPane scr2 =new JScrollPane(area_chatRoomInfo);
pan.add(scr2, BorderLayout.CENTER);
pan.add(pan1, BorderLayout.SOUTH);
area_inputInfo.setBorder(BorderFactory.createEtchedBorder());
pan.setBorder(BorderFactory.createTitledBorder("Chatroot Information"));
scr.setOpaque(false);
scr.getViewport().setOpaque(false);
scr2.setOpaque(false);
scr2.getViewport().setOpaque(false);
pan.setOpaque(false);
pan1.setOpaque(false);
pan2.setOpaque(false);
pan3.setOpaque(false);
return pan;
}
private Container getRightContainer(){
JPanel pan = new JPanel();
JScrollPane scr = new JScrollPane(area_onlineUserList);
pan.add(scr);
pan.setBorder(BorderFactory.createTitledBorder("Online User List"));
scr.setOpaque(false);
scr.getViewport().setOpaque(false);
pan.setOpaque(false);
return pan;
}
/*add listener */
private void addListener(){
/*send button add Listener*/
but_send.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sendMessage();
area_inputInfo.requestFocus();
}
});
/*alt + s */
but_send.setMnemonic(KeyEvent.VK_S);
/*clear button add listener*/
but_clear.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ChatRoom.this.area_chatRoomInfo.setText("");
}
});
/*window close */
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
try{
ChatRoom.this.clientConnection.sendMessage("client close", "5");
}catch(Exception ex){
ex.printStackTrace();
}
}
});
}
/**
*send message
*/
private void sendMessage(){
String message = this.area_inputInfo.getText();
if(!"".equals(message)){
this.area_inputInfo.setText("");
this.clientConnection.sendMessage(message, "2");
}
}
}
package org.zbq.client;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.List;
import javax.swing.JOptionPane;
import org.zbq.util.CharUtil;
import org.zbq.util.XMLUtil;
public class ClientConnection extends Thread {
private String hostAddress;
private int port;
private String userName;
private ClientLogin client;
private Socket socket;
private InputStream input;
private OutputStream output;
private ChatRoom chatRoom;
public ClientConnection(ClientLogin client, String serverAddr, int port, String userName) {
this.client = client;
this.hostAddress = serverAddr;
this.port = port;
this.userName = userName;
this.connect2Server();
}
/**
* connect to server
*/
private void connect2Server() {
try {
this.socket = new Socket(this.hostAddress, this.port);
this.input = this.socket.getInputStream();
this.output = this.socket.getOutputStream();
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "connect to server error!", "ERROR", JOptionPane.YES_OPTION);
e.printStackTrace();
}
}
public boolean login(){
String xml = XMLUtil.constructLoginXML(userName);
try {
output.write(xml.getBytes());
byte[] buf = new byte[5000];
int len = input.read(buf);
String loginResultXML = new String(buf, 0, len);
String loginResult = XMLUtil.extractLoginResult(loginResultXML);
if("success".equals(loginResult)){
this.chatRoom = new ChatRoom(this, userName);
this.client.getFrame().setVisible(false);
return true;
}
return false;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public Socket getSocket() {
return socket;
}
/**
*
* @param message
* @param type
* send message to server
*/
public void sendMessage(String message, String type){
try {
int t = Integer.parseInt(type);
String xml = null;
/*client send message to server*/
if(CharUtil.CLIENT_MESSAGE == t){
xml = XMLUtil.constructMessageXML(userName, message);
/*client send message to server for close the window */
}else if(CharUtil.CLOSE_CLIENT_WINDOW == t){
xml = XMLUtil.constructCloseClientWindowXML(userName);
}
output.write(xml.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(true){
byte[] buf = new byte[5000];
try {
int len = input.read(buf);
String xml = new String(buf, 0, len);
int type = Integer.parseInt(XMLUtil.extractType(xml));
/*update user list*/
if(CharUtil.USER_LIST == type){
List<String> list = XMLUtil.extractUserList(xml);
StringBuffer buff = new StringBuffer();
for(String user : list){
buff.append(user + "\n");
}
this.chatRoom.getArea_onlineUserList().setText(buff.toString());
/*server send to client chat message*/
}else if(CharUtil.SERVER_MESSAGE == type){
String content = XMLUtil.extractContent(xml);
this.chatRoom.getArea_chatRoomInfo().append(content + "\n");
/*close the client window*/
}else if(CharUtil.CLOSE_SERVER_WINDOW == type){
JOptionPane.showMessageDialog(null, "The Server already close, the program will exit",
"Information", JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
/*confirmation the client close*/
}else if(CharUtil.CLOSE_CLIENT_WINODW_CONFIRMATION == type){
try{
// this.getSocket().getOutputStream().close();
// this.getSocket().getInputStream().close();
this.getSocket().close();
}catch (Exception e){
e.printStackTrace();
}finally{
System.exit(0);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}