最近需要学习下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-------
}