黑马程序员技术交流社区
标题:
关于Socket和GUI的一个程序问题!求解啊!
[打印本页]
作者:
桃华月禅
时间:
2014-3-14 17:43
标题:
关于Socket和GUI的一个程序问题!求解啊!
正在学习Socket编程,学到了聊天程序,用命令行的方式确实简单实现了,可是自己尝试用GUI做成图形化界面却不知为什么报错?来向即将进黑马学哥学姐求解!
实现效果就是QQ那样的聊天界面。
错误是运行时异常:
第一次点击按钮无论是发送还是接受数据都没问题,可是第二次点击发送按钮就会提示异常。
经过检验是ds.send(dp)那里抛了IOEeption,可是为什么第一次没抛,反而之后的每次都抛呢?真的想不通!
程序代码如下:
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
class ChattingFrameTest
{
public static void main(String[] args)throws Exception{
DatagramSocket dsSend = new DatagramSocket();
DatagramSocket dsReceive = new DatagramSocket(10000);
new ChattingFrame(dsSend,dsReceive);
}
}
class ChattingFrame
{
private Frame f;
private TextArea taSend,taReceive;
private Panel pSend,pReceive;
private Button b;
private DatagramSocket dsSend,dsReceive;
ChattingFrame(DatagramSocket dsSend,DatagramSocket dsReceive){
this.dsSend = dsSend;
this.dsReceive = dsReceive;
init();
}
public void init(){
f = new Frame("聊天程序");
f.setBounds(400,200,500,420);
f.setLayout(new BorderLayout(10,10));
//建立上下主面板
pSend = new Panel();
pSend.setPreferredSize(new Dimension(300,100));
pReceive = new Panel();
pReceive.setPreferredSize(new Dimension(300,300));
//布局下边的发送面板内的内容
pSend.setLayout(new BorderLayout(10,10));
taSend = new TextArea();
taSend.setPreferredSize(new Dimension(250,60));
b = new Button("发送");
b.setPreferredSize(new Dimension(30,20));
pSend.add(taSend,BorderLayout.CENTER);
pSend.add(b,BorderLayout.EAST);
//布局上边接收面板的内容
pReceive.setLayout(new BorderLayout());
taReceive = new TextArea();
pReceive.add(taReceive);
//把主面板添加进窗体内
f.add(pSend,BorderLayout.SOUTH);
f.add(pReceive,BorderLayout.CENTER);
myEvent();
f.setVisible(true);
}
public void myEvent(){
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
Receive r = new Receive(dsReceive);
new Thread(new Send(dsSend,taSend.getText())).start();
new Thread(r).start();
try{Thread.sleep(1000);}catch(Exception ei){}
taReceive.append(r.getReceive());
taSend.setText("");
}
});
}
}
class Send implements Runnable
{
private DatagramSocket ds;
private String taSend;
Send(DatagramSocket ds,String taSend){
this.ds = ds;
this.taSend = taSend;
}
public void run(){
try
{
if(taSend==null)
return;
byte[] buf = taSend.getBytes();
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getLocalHost(),10000);
ds.send(dp);
ds.close();
}
catch (UnknownHostException e)
{
throw new RuntimeException("未知主机");
}
catch(IOException e)
{
throw new RuntimeException("IO异常");
}
}
}
class Receive implements Runnable
{
private DatagramSocket ds;
private String taReceive;
Receive(DatagramSocket ds){
this.ds = ds;
}
public void run(){
try
{
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
taReceive = dp.getAddress().getHostName()+": \r\n"+new String(dp.getData(),0,dp.getLength())+"\r\n";
}
catch (Exception e)
{
throw new RuntimeException("接收出现错误");
}
}
public String getReceive(){
return taReceive;
}
}
复制代码
作者:
daoyua
时间:
2014-3-14 17:51
你把发送那个不要close,因为程序在运行,你关闭了socket第二次怎么发啊,同个线程调用的是一个socket,你试试呢,
作者:
桃华月禅
时间:
2014-3-14 18:00
daoyua 发表于 2014-3-14 17:51
你把发送那个不要close,因为程序在运行,你关闭了socket第二次怎么发啊,同个线程调用的是一个socket,你 ...
不是吧,真的是这么蛋疼的问题,问题确实出现在这里!
自己想了2个多小时都没解决,来这里提问1min就解决了....不是吧,来这里真是来对了= =........
谢谢你的回答,我还需要努力啊。
这个以后确实得注意,都忘了DatagramSocket只建了一个,不能关闭的!
作者:
daoyua
时间:
2014-3-14 18:01
因为我和你犯过同样的错,只不过我是输出流~
作者:
桃华月禅
时间:
2014-3-14 18:35
虽说完善程序时还是有点小问题没搞清,不过感觉自己能想出来,总之谢谢了。
继续学习中,不过我不是黑马的学员,虽说可能以后会是,不过我在这里问问题没问题吗?
作者:
daoyua
时间:
2014-3-14 18:42
这是技术交流的地方,我也才报名啊,没事的
作者:
桃华月禅
时间:
2014-3-14 18:47
嗯!
这个技术分是什么?我只知道貌似报名时需要,这么容易就给我一年后我不就得好几百分了吗...
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2