A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

王达

初级黑马

  • 黑马币:0

  • 帖子:32

  • 精华:0

© 王达 初级黑马   /  2012-7-2 13:08  /  1621 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

看完了java基础视频,自己用udp编一个简单的带图形化界面的qq程序,运行的时候总是报错,报的错是空指针和socket closed,但是找不到啊,求高人指点啊。。。
代码如下:

import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
class Awt
{
private Frame f;
private TextArea area;
private TextField field;
public void awtFrame() throws Exception
{
  f=new Frame("对话中");
  f.setLayout(new FlowLayout());
  f.setBounds(400,300,600,500);
  area=new TextArea(20,60);
  field=new TextField(30);
  f.add(area);
  f.add(field);
  f.addWindowListener(new WindowAdapter()
  {
   public void windowClosing(WindowEvent e)
   {
    System.exit(0);
   }
  });
  f.setVisible(true);
  
}
public Frame getf()
{
  return f;
}
public TextArea getta()
{
  return area;
}
public TextField gettf()
{
  return field;
}
}

class QQTest
{
public static void main(String[] args)  throws Exception
{
  Awt awt=new Awt();
  awt.awtFrame();
  DatagramSocket socket1=new DatagramSocket();
  DatagramSocket socket2=new DatagramSocket(10006);
  new Thread(new Receive(socket2,awt)).start();
  new Thread(new Send(socket1,awt)).start();
}
}
class Send implements Runnable //需要文本框,窗体,文本区域。
{
private DatagramSocket socket;
private Awt awt;
Send(DatagramSocket socket,Awt awt)
{
  this.socket=socket;
  this.awt=awt;
}
byte[] buf=null;
public void run()
{
  try
  {
   awt.getf().addKeyListener(new KeyAdapter()
   {
    public void keyPressed(KeyEvent e)
    {
     if(e.getKeyCode()==KeyEvent.VK_ENTER)
     {
      String str=awt.gettf().getText();
      buf=str.getBytes();
      awt.getta().append(str);  
     }
    }
   });
   DatagramPacket packet=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10006);      
   socket.send(packet);
   awt.gettf().setText("");
   //packet.setData(buf);
  }
  catch (Exception ex)
  {
   System.out.println(ex.getMessage()+"==="+ex.toString());//throw new RuntimeException("发送错误");//==========
  }
  finally
  {
   socket.close();
  }
  
}
}
class Receive implements Runnable//需要文本区域
{
private DatagramSocket socket;
private Awt awt;
Receive(DatagramSocket socket,Awt awt)
{
  this.socket=socket;
  this.awt=awt;
}
public void run()
{
  try
  {
   byte[] buf=new byte[1024*1024*64];
   DatagramPacket packet=new DatagramPacket(buf,buf.length);
   socket.receive(packet);
   String ip=packet.getAddress().getHostName();
   String data=new String(packet.getData(),0,packet.getLength());
   awt.getta().append(ip+":"+data);
  }
  catch (Exception ex)
  {
   System.out.println(ex.getMessage()+"==="+ex.toString());//throw new RuntimeException("接收错误");//=================
  }
  finally
  {
   socket.close();
  }
}
}

4 个回复

倒序浏览
没有人指点一下吗
回复 使用道具 举报
几个重要的问题:
1.Send类里面
awt.getf().addKeyListener(new KeyAdapter() {
这一行KeyListener应该加在field上
所以改为
awt.gettf().addKeyListener(new KeyAdapter() {

2.Send类里面
这一段
DatagramPacket packet = new DatagramPacket(buf, buf.length,InetAddress.getByName("192.168.1.255"), 10006);
socket.send(packet);
awt.gettf().setText("");
执行完上面的添加监听器
就会马上执行
而这是buf还是null
所以扔空指针异常
而且应该发完一句话还可以发
所以用一个while(buf!=null)围起来

3.Receive类里面
byte[] buf = new byte[1024 * 1024 * 64];
这个太大了
改为
byte[] buf = new byte[1024 * 64];
即可

4.Receive类里面
同样Send,接受数据后不应结束线程
用while(true)把
socket.receive(packet);
String ip = packet.getAddress().getHostName();
String data = new String(packet.getData(), 0, packet.getLength());
awt.getta().append(ip + ":" + data);
这一段围起来


修改上面4个问题后即可运行成功
但是还有不少细节地方要修改
比如发送后清空下面的Field
上面的textarea应该不能被编辑
且上面的textarea显示消息时
前面应该加上IP地址等等
回复 使用道具 举报
本帖最后由 王达 于 2012-7-6 08:55 编辑
温少邦 发表于 2012-7-5 23:27
几个重要的问题:
1.Send类里面
awt.getf().addKeyListener(new KeyAdapter() {


多谢了,看见那个f了。。。不过2里边的那个,我的packet都已经装好数据发出去了让Area去接收了啊,这边的buf是空的不会影响我的Area接收吧,而且我不加循环应该不至于会不能运行吧
回复 使用道具 举报
Send那边执行完下一句
马上就会执行
DatagramPacket packet=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10006);  
这一句,这时候你的buf还是nul
不加循环的话
你的send函数在你运行的一瞬间已经结束了而且buf还是null
不过感觉最好不用循环
把新建DatagramPacket
还有发送这堆代码放进Listener的keyPressed函数里
按一次调用一次
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马