当前位置:编程学习 > JAVA >>

java 聊天室 代码问题 不能同时两个用户登录

服务端

package server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;


public class Server {
/*serversocket*/
private ServerSocket sSocket;
/*allUsers*/
private Map<String,Socket> allUsers;
/*
 * 创建监听服务 
 * */
public Server(){
try{
//在9090端口创建一个监听服务
sSocket =new ServerSocket(9090);
allUsers=new Hashtable<String,Socket>();
}catch(Exception e){
e.printStackTrace();
}
}
/*
 * 启动监听服务
 * */
public void startServerSocket(){
Socket s=null;
try{
//执行accept()方法使得ServerSocket处于等待状态,随时监听client
s=sSocket.accept();
new ServerThread(s).start();
}catch(Exception e){
e.printStackTrace();
}
}

public class ServerThread extends Thread{
private Socket s;
private BufferedReader br;
private PrintWriter pw;

public ServerThread(Socket s) {
try{
this.s = s;
this.br =new BufferedReader(new InputStreamReader(s.getInputStream()));
this.pw =new PrintWriter(s.getOutputStream()) ;
}catch(Exception e){
e.printStackTrace();
}
}

public void run(){
        while(true){
         String comm=null;
            try {
                comm = br.readLine();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            System.out.println("comm"+comm);
            if(comm.split(":")[0].equals("%LOGIN%")){
                String userName=comm.split(":")[1];
                if(allUsers.containsKey(userName)){
                    pw.println("%LOGIN%:REFUSE");
                    pw.flush();
                }else{
                    pw.println("%LOGIN%:OK");
                    pw.flush();
                    allUsers.put(userName, s);
                    sendMessageToAllClient("%MESSAGE%:SYSTEM:所有人:"+userName+"进入聊天室!");
                    sendOnlineUserList();
                }
            }else if(comm.split(":")[0].equals("%MESSAGE%")){
                String to=comm.split(":")[2];
                if(to.equals("所有人")){
                 sendMessageToAllClient(comm);
                }else {
                 sendMessageToClient(comm,to);
                }
            }else if(comm.split(":")[0].equals("%EXIT%")){
                String user=comm.split(":")[1];
                allUsers.remove(user);
                sendMessageToAllClient("%MESSAGE%:SYSTEM:所有人:"+user+"离开聊天室!");
                sendOnlineUserList();
                try {
                 s.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }

/*
 * 用户列表
 * */

private void sendOnlineUserList(){
        Set<String> userSet=allUsers.keySet();
        Object[] userArray=userSet.toArray();
        StringBuffer userListString=new StringBuffer();
        for(int i=0;i<userArray.length;i++){
            userListString.append(userArray[i]);
            if(i<userArray.length-1){
                userListString.append(";");
            }
        }
        this.sendMessageToAllClient("%USERLIST%:"+userListString);
    }
    
private void sendMessageToClient(String mesg,String clientUserName){
        Socket temp_s=allUsers.get(clientUserName);
        PrintWriter pw=null;
        try {
            pw=new PrintWriter(temp_s.getOutputStream());
            pw.println(mesg+"\t["+new Date()+"]");
            pw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    



private void sendMessageToAllClient(String mesg){
        Collection<Socket> coll=allUsers.values();
        Date date=new Date();
        
        for(Socket temp_s:coll){
            PrintWriter pw=null;
            try {
                pw = new PrintWriter(temp_s.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
            if(mesg.split(":")[0].equals("%MESSAGE%")){
                pw.println(mesg+"\t["+date+"]");
                pw.flush();
            }else {
                pw.println(mesg);
                pw.flush();
            }
        
        }
    }
}



public static void main(String[] args) {
        new Server().startServerSocket();
    }
}



--------------------编程问答-------------------- 客户端

package client;


import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
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;

public class Client {
/*
 * 界面控件
 * */
    private JFrame frame;
    private JTextArea area;
    private JLabel label;
    private JComboBox box;
    private JTextField field;
    private JButton button;
    private JPanel eastPanel;
    
    private Socket s;
    private PrintWriter pw;
    private BufferedReader br;
    
    private List<String> onlineUserList;
    
    private String userName;
    /*
     * 客户端加载
     * */
    public Client(){
     /*
      * 创建套接字
      * */
        createSocket();
        /*
         * 登陆方法
         * */
        login();
        onlineUserList=new ArrayList<String>();
        frame=new JFrame("聊天");
        area=new JTextArea(20,40);
        label=new JLabel(userName);
        box=new JComboBox();
        field=new JTextField(25);
        button=new JButton("发送");
        /*
         * 初始化方法
         * */
        init();
        addEventHandler();
    }
    
    /*
     * 创建socket和输入输出流对象
     * */
    private void createSocket(){
        try {
        
         InetAddress inet = InetAddress.getLocalHost();
         System.out.println("本机IP:"+inet.getHostAddress());
            
            s=new Socket(inet.getHostAddress(),9090);
            pw=new PrintWriter(s.getOutputStream());
            br=new BufferedReader(new InputStreamReader(s.getInputStream()));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private void login(){
        do {
            String str = JOptionPane.showInputDialog(frame, "请输入昵称:");
            pw.println("%LOGIN%:" + str);
            pw.flush();
            
            String response=null;
            try {
                response = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (response!=null && response.split(":")[0].equals("%LOGIN%")
                    && response.split(":")[1].equals("OK")) {
            
                userName=str;
                break;
            } else {
                JOptionPane.showMessageDialog(frame, "已经存在同名昵称,请重新输入!");
            }
        } while (true);        
    }
    /*
     * 初始化方法
     * */
    private void init(){
        frame.setLayout(new BorderLayout());
        JScrollPane jsp=new JScrollPane(area);
        frame.add(jsp,BorderLayout.CENTER);
        
        JPanel southPanel=new JPanel();
        southPanel.setLayout(new FlowLayout());
        southPanel.add(label);
        southPanel.add(new JLabel(" 对 "));
        southPanel.add(box);
        southPanel.add(new JLabel("说:"));
        southPanel.add(field);
        southPanel.add(button);
        frame.add(southPanel,BorderLayout.SOUTH);
        
        eastPanel=new JPanel();
        eastPanel.setLayout(new BoxLayout(eastPanel,BoxLayout.Y_AXIS));
        eastPanel.add(new JLabel("在线用户列表:"));
        frame.add(eastPanel,BorderLayout.EAST);    
        
    }
    
    private void addEventHandler(){
        ActionListener lis=new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                if(field.getText().trim().equals("")){
                    JOptionPane.showMessageDialog(frame, "不能发送空消息!");
                    return;
                }
                String str="%MESSAGE%:"+userName+":"+box.getSelectedItem()+":"+field.getText();
                pw.println(str);
                pw.flush();
                field.setText("");
            }
        };
        
        button.addActionListener(lis);
        field.addActionListener(lis);
        
        frame.addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent e) {
                int op=JOptionPane.showConfirmDialog(frame, "确定要离开聊天室吗?","确认退出",JOptionPane.YES_NO_OPTION);
                if(op==JOptionPane.YES_OPTION){
                    pw.println("%EXIT%:"+userName);
                    pw.flush();
                    try {
                        Thread.sleep(300);
                        s.close();
                    } catch (InterruptedException e1) {
                        e1.printStackTrace();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                    System.exit(0);
                }
            }
        });
    }
    
    private void reflushUserList(){
        box.removeAllItems();
        box.addItem("所有人");
        eastPanel.removeAll();
        eastPanel.add(new JLabel("在线用户列表:"));
        eastPanel.add(new JButton("所有人"));
        JButton but;
        for(String user:onlineUserList){
            box.addItem(user);
            eastPanel.add(but=new JButton(user));
            but.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent e) {
                    String str=e.getActionCommand();
                    box.setSelectedItem(str);
                }
            });
        }
    }
    
    public void showMe(){
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        
        new ReadMessageThread().start();
    }
    
    class ReadMessageThread extends Thread{
        public void run(){
            while(true){
                String comm=null;
                try {
                    comm = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if(comm==null){
                    continue;
                }
                if(comm.split(":")[0].equals("%MESSAGE%")){
                    String from=comm.split(":")[1];
                    String to=comm.split(":")[2];
                    String content=comm.split(":")[3];
                    System.out.println("content"+content);
                    if(from.equals("SYSTEM")){
                        area.append("[系统消息]:"+content+"\n");
                    }else{
                        area.append(from+" 对 "+to+" 说:"+content+"\n");
                    }
                }else if(comm.split(":")[0].equals("%USERLIST%")){
                    String[] userArray=comm.split(":")[1].split(";");
                    onlineUserList.clear();
                    for(String user:userArray){
                        onlineUserList.add(user);
                    }
                    reflushUserList();
                }
            }
        }
    }
    
    public static void main(String[] args){
        new Client().showMe();
    }

}

--------------------编程问答-------------------- 你现在的问题是啥??? --------------------编程问答-------------------- 不能接受两个客户端主要是服务器的问题,你的那个函数
public void startServerSocket(){
        Socket s=null;
        try{
            //执行accept()方法使得ServerSocket处于等待状态,随时监听client
            s=sSocket.accept();
            new ServerThread(s).start();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
这样写只能接受一个客户端,如果你想接受多个,必须有一个死循环重复执行 s=sSocket.accept();这个方法:
你把这个方法的代码改成这样试试:
public void startServerSocket(){
        Socket s=null;
         while(true){//---------------------外面包装一个死循环
        try{
            //执行accept()方法使得ServerSocket处于等待状态,随时监听client
            s=sSocket.accept();
            new ServerThread(s).start();
        }catch(Exception e){
            e.printStackTrace();
        }
          }//------------------------------------------------------
    }
--------------------编程问答-------------------- --------------------编程问答--------------------  - -。。这个是j2se的问题。。发对地方就帮你解决。。。 --------------------编程问答-------------------- --------------------编程问答-------------------- 线程....................... --------------------编程问答-------------------- 3楼基本上说到点子了,你服务端要阻塞式等待,即需要一个死循环,等待客户端链接进来,不然你有一个客户端连接进来,服务端程序就走完了。 --------------------编程问答-------------------- 把你那个函数加个死循环
public void startServerSocket(){
        Socket s=null;

     try{
        while(true){
            //执行accept()方法使得ServerSocket处于等待状态,随时监听client
            s=sSocket.accept();
            new ServerThread(s).start();
        }
        }catch(Exception e){
            e.printStackTrace();
        }

    }
就可以了。
补充:Java ,  J2ME
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,