本帖最后由 axr1985lazy 于 2014-07-21 21:53:17 编辑

解决方案 »

  1.   

    问题一不是很明白,问题二改成if(!msg.equals(""))
    试试
      

  2.   

    1、第一个问题我也没搞清楚,但我把程序简单改了下之后(接收端口和发送端口通过构造函数传递,调试也方便了),这个问题就没出现了(那个chatframe类的initial函数中创建发送线程的那个代码我也注释掉了),
    这句InetAddress.getByName("192.168.1.106")我改成InetAddress.getByName("localhost"),这样换台机子调试也方便
    2、第二个问题比较简单:msg=write.getText(),在默认情况下,也就是你write中什么都没输入的情况下,getText()方法返回的是一个空字符串即“”,空字符串跟null不是一个概念;所以你用msg!=null来判断肯定不行,msg肯定不等于null
    比如:
    String msg=null,则说明msg当前是个空引用,没有指向任何有效的String对象
    而String msg=“”,则意思是msg当前指向一个有效的String对象,只不过这个String对象的值是“”而已
    你查下api文档了解下TextArea类的getText方法,以及区分下null和“”就明白啦
    3、修改后的代码及结果
    package lesson10;
    import java.io.*;
    import java.net.*;
    import java.awt.*;
    import java.awt.event.*;class ChatFrame
    {
    //定义图形化界面的各个组件
    private Frame f;
    private TextArea write, show;
    private Button but; //定义了两个线程,分别控制发送端和接收端
    private Thread send, rece; //定义了连个Socket服务,分别负责发送和接收
    private DatagramSocket sendSocket, receSocket; //接收端端口
    private int recePort = 6000;
    private int targetPort=6001;
    private String name;
    //构造函数
    ChatFrame(String name,int recePort,int targetPort)
    {
    this.name=name;
    this.recePort=recePort;
    this.targetPort=targetPort;
    //进行各种初始化的方法
    initial();
    } //初始化函数
    public void initial()
    {
    //定义主窗体
    f = new Frame(name);
    f.setBounds(300, 100, 400, 600);
    f.setLayout(new FlowLayout()); //发送按钮
    but = new Button("发送"); //输入文本区域和显示文本区域
    write = new TextArea(15, 50);
    show = new TextArea(15, 50); //向窗体中添加组件
    f.add(show);
    f.add(write);
    f.add(but); try
    {
    //创建两个Socket服务,分别负责发送信息和接收信息
    sendSocket = new DatagramSocket();
    receSocket = new DatagramSocket(recePort);//传入接收端端口
    }
    catch(Exception e)
    {
    throw new RuntimeException("Socket服务创建失败!");
    } //开启事件监听
    chatEvent();

    //创建两个线程,分别控制发送端和接收端
    //send = new Thread(new Send(sendSocket, write, show));//参数分别为发送Socket服务,主窗体中的输入文本区和显示文本区
    rece = new Thread(new Receive(receSocket, show));//参数分别为接收Socket服务,主窗体为显示文本区 //开启接收端线程
    //send.start();
    rece.start(); //显示主窗体
    f.setVisible(true);
    } //为主窗体定义事件监听机制
    public void chatEvent()
    {
    //为发送按钮添加事件监听器
    but.addActionListener(new ActionListener()
    {
    //当按钮被按下时,再次创建一个发送端线程,参数同上,并执行该线程
    public void actionPerformed(ActionEvent e)
    {
    send = new Thread(new Send(sendSocket, write, show,targetPort));
    send.start();
    }
    }); //为显示文本区添加事件监听器
    show.addKeyListener(new KeyAdapter()
    {
    //不允许对显示文本区进行任何键盘操作
    public void keyPressed(KeyEvent e)
    {
    e.consume();
    }
    }); //关闭主窗体监听器
    f.addWindowListener(new WindowAdapter()
    {
    public void windowClosing(WindowEvent e)
    {
    System.exit(0);
    }
    });
    }
    }//定义发送端线程
    class Send implements Runnable
    {
    //定义Socket服务,输入和显示文本区
    private DatagramSocket ds;
    private TextArea write, show;
    //发送目标设备端口
    private int targetPort = 6001; //构造函数
    Send(DatagramSocket ds, TextArea write, TextArea show,int targetPort)
    {
    this.ds = ds;
    this.write = write;
    this.show = show;
    this.targetPort = targetPort;
    } //执行体
    public void run()
    {
    String msg = null;
    DatagramPacket dp = null;
    byte[] buf = null;
    try
    {
    //获取输入文本的文本,并发送至目标设备
    msg = write.getText();

    //仅在文本区不为空时执行
    if(!("".equals(msg)))
    {
    //将字符串转换为字节数组
    buf = msg.getBytes();
    //将文本(字符串)打包成数据报包
    dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("localhost"), targetPort); ds.send(dp); if("over".equals(msg))
    return; //在显示文本区,显示所发送的内容
    show.append("我说:"+msg+"\n");
    //清空输入文本区
    write.setText("");
    }
    }
    catch (Exception e)
    {
    throw new RuntimeException("数据发送失败!");
    }
    }
    }class Receive implements Runnable
    {
    //定义了Socket服务和显示文本区
    private DatagramSocket ds;
    private TextArea show;
    //构造函数
    Receive(DatagramSocket ds, TextArea show)
    {
    this.ds = ds;
    this.show = show;
    }
    //执行体
    public void run()
    {
    byte[] buf = new byte[1024*64];
    DatagramPacket dp = null;
    String ip = null, data = null; try
    {
    while(true)
    {
    //将字节缓存打包成数据报包,用于接收数据
    dp = new DatagramPacket(buf, buf.length);
    //接收数据
    ds.receive(dp);

    //获取对方设备IP地址和数据
    ip = dp.getAddress().getHostAddress();
    data = new String(dp.getData(), 0, dp.getLength()); if("over".equals(data))
    {
    System.out.println(ip+"离开了聊天室");
    break;
    } //在显示文本区显示接收到的信息
    show.append(ip+"::"+data+"\n");
    }
    }
    catch(Exception e)
    {
    throw new RuntimeException("数据接收失败!");
    }
    }
    }public class Demo7 
    {
    public static void main(String[] args) 
    {
    //new ChatFrame("李四",6000,6001);
    new ChatFrame("王五",6001,6000);
    }
    }我是先启动李四的,后启动王五的