| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1340 人关注过本帖
标题:有谁愿意帮我检查一下我的聊天室哪里错了??
只看楼主 加入收藏
Javapet
Rank: 1
等 级:禁止访问
帖 子:80
专家分:0
注 册:2008-1-5
结帖率:50%
收藏
 问题点数:0 回复次数:9 
有谁愿意帮我检查一下我的聊天室哪里错了??
上个月写了一个简单的聊天室,但功能不全,只能用客户端对客户端的形式进行对话,在服务器中不能发信息,但当进行客户之间谈话时,就偶尔出现了收不到信息的错误,我花了很多时间也找不到错误的所在.........如果大家愿意的话,请帮我看看究竟是怎么回事,谢谢了!
aaaa.rar (6.05 KB)


//服务器端程序:
//11开头表示新加入了聊天用户;22开头表示公聊;33开头表示私聊

import *;
import javax.swing.*;
import java.awt.*;
import javax.swing.border.TitledBorder;
import java.awt.event.*;
import *;
import java.util.*;

public class Server1 extends JFrame
{
        JTextArea JT2;   // "聊天记录"那个文本域
        JTextArea JT3;     // "发送信息"那个文本域
        JButton B1;             // "发送"按钮
        JButton B2;      // "删除"按钮
        final JCheckBox JC;        //"发送给所有用户"复选框
        TitledBorder TB1;            //"参与者"边框
        TitledBorder TB2;            //"聊天记录"边框
        TitledBorder TB3;            //"发送信息"边框
        Socket s;                            //客户端套接字
        BufferedReader BR;        
        PrintWriter PW;
        boolean bool=false;
        boolean flag=true;
        //String line=System.getProperty("line.separator");         //起到换行作用
        HashMap map=new HashMap();                                                     //用来储存socket和用户名
        JList userList=new JList();                                                     //用来显示参与者
        DefaultListModel ListModel=new DefaultListModel();    
        Vector ve=new Vector();                                                             //用来储存用户名
        
        public Server1(String str)
        {
                super(str);
                this.getContentPane().setLayout(null);                     //设置主窗口的布局管理器为空
                //创建组件
                JT2=new JTextArea(60,30);
              JT2.setCaretPosition(JT2.getText().length());
                JT3=new JTextArea(60,30);
                B1=new JButton("发送");
                B2=new JButton("删除");
                JC=new JCheckBox("发送给所有用户");
                TB1=BorderFactory.createTitledBorder("参与者");
                TB2=BorderFactory.createTitledBorder("聊天记录");
                TB3=BorderFactory.createTitledBorder("发送信息");
                
                //创建面板
                JPanel JP1=new JPanel();
                JPanel JP2=new JPanel();
                JPanel JP3=new JPanel();
                JPanel JP4=new JPanel();
                JPanel JP5=new JPanel();
                
                //布置JP1面板
                JP1.setLayout(new GridLayout(1,1));
                userList.setModel(ListModel);
                JScrollPane JS=new JScrollPane(userList);            //创建滚动条
                JS.setBorder(TB1);                                                        //添加边框
                JP1.add(JS);                                                            
                JP1.setBounds(7,10,150,425);                                    //设置JP1面板的大小和坐标
                this.getContentPane().add(JP1);                                //先用getContentPane()返回主窗口的面板,再在此面板中添加JP1
                
                //布置JP2面板
                JP2.add(JC);
                JP2.setBounds(30,432,150,50);
                this.getContentPane().add(JP2);
                
                 //布置JP3面板
                JP3.setLayout(new GridLayout(1,1));
                JT2.setEditable(false);                                                //设置JT2文本域不可编辑
                JScrollPane JSP2=new JScrollPane(JT2);
                JSP2.setBorder(TB2);
                JP3.add(JSP2);
                JP3.setBounds(160,10,380,250);
                this.getContentPane().add(JP3);
                
                //布置JP4面板
                JP4.setLayout(new GridLayout(1,1));
                JScrollPane JSP3=new JScrollPane(JT3);
                JSP3.setBorder(TB3);
                JP4.add(JSP3);
                JP4.setBounds(160,258,380,177);
                this.getContentPane().add(JP4);
                
                //布置JP5面板
                JLabel j=new JLabel("   ");                                             //此标签只起分隔B1和B2的作用
                JP5.add(B1);
                JP5.add(j);
                JP5.add(B2);
                JP5.setBounds(350,430,200,35);
                this.getContentPane().add(JP5);
                this.pack();                                                                         //用来整理组件的空隙
                B1.addMouseListener(new action());                         //为B1添加监听器,"acion"是一个类,在下面定义了
                JC.addActionListener(new ActionListener()                //为JC添加监听器
                                                         {
                                                                     public void actionPerformed(ActionEvent e)
                                                                     {
                                                                             bool=JC.isSelected();                //用来标志此复选按钮是否被打勾
                                                                     }
                                                         });
        }
        public void receive()                //接收用户信息
        {
              try
                {
                        ServerSocket ss=new ServerSocket(8000);                //定义服务器套接字
                        while(flag)
                        {
                                s=ss.accept();                 //接收用户的请求,并创建一个客户端套接字
                                work w=new work(s);    //创建线程 w
                                w.start();                         //启动线程
                      }
                }
                catch(Exception e)
                {
                        e.printStackTrace();    
              }
        }
        class action extends MouseAdapter                    //自定义监听器
        {   
                public void mousePressed(MouseEvent e)        //鼠标按下所以触发的事件
                {
                        String str=JT3.getText();                        //获取"发送信息"文本域的内容
                        PW.println(str);                                        //向对应的输出流输出str
                        JT3.setText("");                                        //设置"发送信息"文本域为空
                }
        }
        class work extends Thread                                //线程类
        {
              Socket s;                                                            
                public work(Socket s)                                
                {
                        this.s=s;
                }
                public void run()
                {
                      try
                      {
                            InputStream in=s.getInputStream();                    //获取相应的输入流
                            OutputStream out=s.getOutputStream();                //获取相应的输出流
                                BR=new BufferedReader(new InputStreamReader(in));        //创建输入流
                                PW=new PrintWriter(out,true);                                                //创建输出流
                                String value;
                                
                                String str=BR.readLine();        //读取从客户段传过来的数据    
                                str=str.trim();                    //读取输入流BR的内容
                                while(str.length()!=0)
                                {
                                      Iterator it;             //定义一个迭代器
                                      int int_1=Integer.parseInt(str.substring(0,2));    //截取str的前两个字符           
                                      String str2=str.substring(2);                      //得到一个以索引2为起点的新字符串
                                      Set keySet_;       //用来保存用户名和相应的Socket
                                      int num;           //Vector数组的元素个数
                                      
                                      switch(int_1)      //验证str的前两个字符
                                      {
                                              case 11:                  //str以"11"开头的,表示新来的用户
                                                      ListModel.addElement(str2);     //在列表中添加新的用户
                                                      ve.add(str2);                    //把用户名添加到Vector数组中
                                                      map.put(s,str2);         //设置用户名的key和值
                                                      num=ve.size();                //返回Vector的元素个数                                         
                                                      keySet_=map.keySet();                //返回所有key,即所有的Socket
                                                      it=keySet_.iterator();            //返回一个迭代器
                                                    while(it.hasNext())         //判断是否具有元素
                                                      {
                                                              Socket s1=(Socket)it.next();     //取得Socket
                                                              value=(String)map.get(s1);       //返回对应Socket的值
                                                              PW=new PrintWriter(s1.getOutputStream(),true);     //创建一个有对应客户端的输出流
                                                              PW.println("00aaaa");           //向对应的Socket客户端传输字符串"00aaaa"(作用:用来告诉客户端要清空用户列表)
                                                              for(int i=0;i<num;i++)
                                                              {
                                                                      if(value!=ve.get(i))       //用来实现不向自己客户端列表发送自己的名字
                                                                      {
                                                                              PW.println("11"+(String)ve.get(i));      //发送以"11"开头的用户名到相应的客户端
                                                                    }    
                                                              }
                                                      }break;
                                              case 22 :             //以"22"开头,表示公聊
                                                      keySet_=map.keySet();                    //返回所有key,即所有的Socket
                                                      it=keySet_.iterator();        //返回一个迭代器
                                                      while(it.hasNext())                        //判断是否具有元素
                                                      {
                                                              Socket s1=(Socket)it.next();        //取得Socket
                                                              if(s1!=s)          //用来实现:不向发信客户端的发送信息
                                                              {
                                                                      PW=new PrintWriter(s1.getOutputStream(),true);        //创建一个有对应客户端的输出流
                                                                      PW.println("22"+map.get(s)+" 对大家说:"+str2);       //向相应的客户端发送以"22"开头的信息
                                                              }
                                                    }break;
                                              case 33 :         //以"33"开头,表示私聊
                                                      int index=str2.indexOf("++");         //用来作为名字标记,因为用户名字后面直接跟上"++"
                                                  String userName=str2.substring(0,index);       //获取str2中包含的用户名
                                                  String str3=str2.substring(index+2);           //获取纯的聊天信息(次信息不包括任何标记,只是纯谈话信息)
                                                      keySet_=map.keySet();
                                                      it=keySet_.iterator();
                                                      while(it.hasNext())
                                                      {
                                                              Socket s1=(Socket)it.next();
                                                              value=(String)map.get(s1);
                                                              if(value.equals(userName))                //当找到相应的要发送的用户时则为真
                                                              {
                                                                      PW=new PrintWriter(s1.getOutputStream(),true);         
                                                                      PW.println("33"+map.get(s)+" 对你说:"+str3);
                                                              }
                                                      }break;
                                      }  
                                        str=BR.readLine();
                                        str=str.trim();       //清楚字符串前后的空白
                              }
                        }
                       catch(Exception e)
                       {
                               e.printStackTrace();
                       }
                }
        }
        public static void main(String[] args)
        {
                Server1 S=new Server1("聊天室服务器");
                S.setSize(550,500);          //设置主窗口的大小
                S.setLocation(150,150);      //设置主窗口的位置
                S.setResizable(false);       //设置主窗口不可改变大小
                S.setVisible(true);          //设置主窗口可见
                S.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         //为主窗口添加关闭的监听器
        S.receive();                 //调用接收信息的方法
        }
}


//客户端端程序:
//11开头表示新加入了聊天用户;22开头表示公聊;33开头表示私聊

import javax.swing.*;
import *;
import java.awt.*;
import javax.swing.border.TitledBorder;
import *;
import java.awt.event.*;

public class Client1 extends JFrame
{
        JTextArea JT2;       // "聊天记录"那个文本域
        JTextArea JT3;       // "发送信息"那个文本域
        JButton B1;
        JButton B2;
        JCheckBox JC;        //"发送给所有用户"复选框
        TitledBorder TB1;    //"参与者"边框
        TitledBorder TB2;    //"聊天记录"边框
        TitledBorder TB3;    //"发送信息"边框
        BufferedReader BR;
        PrintWriter PW;
        boolean bool=false;
        final JList userList=new JList();
        DefaultListModel ListModel=new DefaultListModel();
        //String line=System.getProperty("line.separator");     //起到换行作用
        String userName;
        
        public Client1(String str)
        {
                super(str);
                this.getContentPane().setLayout(null);          //设置主窗口的布局管理器为空
                //创建组件
                JT2=new JTextArea(60,30);
                JT3=new JTextArea(null,60,30);
                B1=new JButton("发送");
                B2=new JButton("离线");
                JC=new JCheckBox("发送给所有用户");
                TB1=BorderFactory.createTitledBorder("参与者");
                TB2=BorderFactory.createTitledBorder("聊天记录");
                TB3=BorderFactory.createTitledBorder("发送信息");
                
                //创建面板
                JPanel JP1=new JPanel();
                JPanel JP2=new JPanel();
                JPanel JP3=new JPanel();
                JPanel JP4=new JPanel();
                JPanel JP5=new JPanel();
                
                //布置JP1面板
                JP1.setLayout(new GridLayout(1,1));
        userList.setModel(ListModel);
                JScrollPane JSP1=new JScrollPane(userList);       //创建滚动条
                JSP1.setBorder(TB1);                                                            //添加边框
                JP1.add(JSP1);
                JP1.setBounds(7,10,150,425);            //设置JP1面板的大小和坐标
                this.getContentPane().add(JP1);         //先用getContentPane()返回主窗口的面板,再在此面板中添加JP1
                
                //布置JP2面板
                JP2.add(JC);
                JP2.setBounds(30,432,150,50);
                this.getContentPane().add(JP2);
                
                 //布置JP3面板
                JP3.setLayout(new GridLayout(1,1));
                JT2.setEditable(false);                //设置JT2文本域不可编辑
                JScrollPane JSP2=new JScrollPane(JT2);
                JSP2.setBorder(TB2);
                JP3.add(JSP2);
                JP3.setBounds(160,10,380,250);
                this.getContentPane().add(JP3);
                
                //布置JP4面板
                JP4.setLayout(new GridLayout(1,1));
                JScrollPane JSP3=new JScrollPane(JT3);
                JSP3.setBorder(TB3);
                JP4.add(JSP3);
                JP4.setBounds(160,258,380,177);
                this.getContentPane().add(JP4);
                
                //布置JP5面板
                JLabel j=new JLabel("   ");           //此标签只起分隔B1和B2的作用
                JP5.add(B1);
                JP5.add(j);
                JP5.add(B2);
                JP5.setBounds(350,430,200,35);
                this.getContentPane().add(JP5);
                this.pack();                              //用来整理组件的空隙
                B1.addMouseListener(new action());        //为"发送"按钮添加监听器
                JC.addActionListener(new ActionListener()
                                                         {
                                                                     public void actionPerformed(ActionEvent e)
                                                                     {
                                                                             bool=JC.isSelected();    //判断复选框是否被打勾
                                                                     }
                                                         });
                userList.addMouseListener(new user());        
        }
    class user extends MouseAdapter
    {
            public void mousePressed(MouseEvent e)
                {
                        userName=(String)userList.getSelectedValue();       //返回当前你选择的用户名
                }            
    }
        public void receive()           //接收信息的方法
        {
              try
              {
                        Socket s=new Socket(InetAddress.getByName(null),8000);           //创建指定IP地址的套接字(Socket)
                        InputStream in=s.getInputStream();                           //获得相应的输入流
                        OutputStream out=s.getOutputStream();                        //获得相应的输出流
                        BR=new BufferedReader(new InputStreamReader(in));            
                        PW=new PrintWriter(out,true);
                        PW.println("11Javapet");            //向服务器发送此客户端的用户名
                        work w=new work();                  //创建一个线程
                        w.start();                          //启动线程
              }
                catch(Exception e)
              {
                      e.printStackTrace();
              }
        }
        class action extends MouseAdapter
      {
                public void mousePressed(MouseEvent e)
                {
                        String str=JT3.getText();         //获取
                        if(str.length()!=0)               //判断输入的信息是否为空
                        {
                                if(userName==null)            //判断是否选中用户名
                                {
                                        if(bool)                  //判断复选框是否被打勾
                                        {
                                              JT2.append("你对所有人说:"+str);        //把你所输入的信息打印到"聊天记录"中
                                                PW.println("22"+str);           //向服务器发送以开头"22"聊天信息,"22"表示公聊
                                      }
                                        userName=null;          //不再选中用户名
                                }
                                else                        //表示信息将要发送到哪个用户名
                                {
                                        if(bool)                //判断复选框是否被打勾
                                        {
                                                JT2.append("你对所有人说:"+str);       //把你所输入的信息打印到"聊天记录"中
                                                PW.println("22"+str);                                                //向服务器发送以开头"22"聊天信息,"22"表示公聊
                                      }
                                      else                    
                                      {
                                              JT2.append("你对 "+userName+" 说:"+str);      //把你所输入的信息打印到"聊天记录"中
                                                PW.println("33"+userName+"++"+str);             //向服务器发送以开头"33"聊天信息,"33"表示私聊
                                      }
                                }
                      }
                }
      }
      class work extends Thread      //此线程主要用来无量循环地接收服务器转发过来的信息
      {
            public void run()
            {
                      while(true)
                        {
                                try
                                {
                                          String str=BR.readLine();
                                          String str2=str.substring(0,2);
                                          int int_=Integer.parseInt(str2);
                                          String str3=str.substring(2);     //获取聊天信息                                          if(str.startsWith("00"))          //判断str是否含有"00",有的话,就把用户列表清空,再等待新的列表名单
                                          {
                                                  ListModel.removeAllElements();
                                          }
                                          else if(int_==11)         //判断是否以"11"开头
                                          {
                                                  ListModel.addElement(str3);     //把用户名添加到列表中
                                          }
                                        else if(int_==22||int_==33)      //判断是否是以"22"或"33"开头
                                          {
                                                  JT2.append(str3);       //把内容添加到"聊天记录"里
                                          }
                                  }
                                  catch(Exception e)
                                  {
                                          e.printStackTrace();
                                  }
                        }
              }
      }
        public static void main(String[] args)
        {
                Client1 C=new Client1("Javapet聊天室");
                C.setSize(550,500);            //设置主窗口的大小
                C.setLocation(150,150);        //设置主窗口的位置
                C.setResizable(false);         //设置主窗口不可改变大小
                C.setVisible(true);            //设置主窗口可见
                C.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     //为主窗口添加关闭的监听器
                C.receive();                   //调用接收信息的方法
        }
}

[[it] 本帖最后由 Javapet 于 2008-4-15 20:00 编辑 [/it]]
搜索更多相关主题的帖子: 聊天室 检查 
2008-04-15 16:33
luyihuaa5201
Rank: 2
等 级:论坛游民
帖 子:254
专家分:10
注 册:2007-3-25
收藏
得分:0 
J2SE论坛中有个一样的!  你照着看哈,我也不是蛮懂!~
2008-04-15 17:41
web023123
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2008-4-16
收藏
得分:0 
- -!这么长。你干嘛不把出错的消息发出来看看
2008-04-16 11:00
web023123
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2008-4-16
收藏
得分:0 
这么长。你干嘛不把运行出错的消息发出来
2008-04-16 11:00
Javapet
Rank: 1
等 级:禁止访问
帖 子:80
专家分:0
注 册:2008-1-5
收藏
得分:0 
这个我在“命令提示”中运行时没有错误的,只是在用的时候有时会收不到信息
2008-04-16 12:32
Starlove
Rank: 1
等 级:新手上路
帖 子:169
专家分:0
注 册:2007-4-26
收藏
得分:0 
似乎是j2se的问题
发错地方了
2008-04-18 15:25
恋轩念伊人
Rank: 5Rank: 5
来 自:湖南衡阳
等 级:贵宾
威 望:19
帖 子:643
专家分:0
注 册:2008-2-23
收藏
得分:0 
发这里也没有很大关系吧

我不是一个随便的人,我随便起来不是人我哦。信不?
2008-04-20 13:34
netstriker
Rank: 1
等 级:新手上路
威 望:1
帖 子:257
专家分:0
注 册:2007-3-24
收藏
得分:0 
已经修改好了,其实问题并不大,只是没有考滤有一种情况而已,同时,如果是服务器跟客户这样来发送信息的话,是有缺憾的,比如,现在这样去跟客户端去发送信息,只有最后一个连接上服务器端的客户端可以跟服务器交流信息.因为这一个PrintWriter是最后连接上服务器的pw对象,所以,这一个方面的话,要再改进.

aaaa.rar (6.16 KB)
2008-04-20 21:13
Javapet
Rank: 1
等 级:禁止访问
帖 子:80
专家分:0
注 册:2008-1-5
收藏
得分:0 
哦,好,我再看看你修改后的代码,真的很感谢你的帮忙!
2008-04-24 15:12
Javapet
Rank: 1
等 级:禁止访问
帖 子:80
专家分:0
注 册:2008-1-5
收藏
得分:0 
你好,很感谢你帮我修改了代码,我想知道我哪种情况没有考虑到?还有,程序在运行时如果各个客户端公聊和私聊不断地替换操作,发送到一定程度时,仍然会出现收不到信息的情况,请问是不是我的程序架构有问题,有人说我的程序是过程式的程序,要求我用oo模式重新设计,不过现在不管是过程式还是oo模式,我只想知道我的程序具体哪里错了,请指教,谢谢了!
2008-04-24 15:55
快速回复:有谁愿意帮我检查一下我的聊天室哪里错了??
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023522 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved