建了一个UDP系统,Client端每次都会重发一次上次已经发送过的信息,有时候又会漏发一些,怎么看都不知道代码哪错了,单步执行也是对的,求各位大神们教教我呀
Client 的代码如下:
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.*;
public class ChatClient extends Frame{
TextField t1;
TextArea t2 ;
volatile String in = null;
volatile boolean flag = false;
ChatClient() {
this.setBounds(200, 200, 500, 500);
this.setVisible(true);
this.setResizable(true);
this.setLayout(new BorderLayout ());
t1 = new TextField(10);
t2 = new TextArea();
t1.addActionListener(new keyEvets() );
this.add(t1,BorderLayout.SOUTH);
this.add(t2,BorderLayout.CENTER);
pack();
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String arg[]) throws Exception {
ChatClient chatclient = new ChatClient();
while(true) {
synchronized (chatclient) {
if(chatclient.flag ==false) {
continue;
}
if(chatclient.flag == true) {
ByteArrayOutputStream a = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(a);
//System.out.println(chatclient.in);
dos.writeUTF(chatclient.in);
chatclient.flag =false;
byte[] buf = new byte[1024];
buf = a.toByteArray();
String h = new String (buf);
System.out.println(h);
DatagramPacket ps = new DatagramPacket(buf,0,buf.length,new InetSocketAddress("127.0.0.1",6666));
DatagramSocket ds = new DatagramSocket(4444);
dos.flush();
ds.send(ps);
ds.close();
}
}
}
}
class keyEvets implements ActionListener {
public void actionPerformed(ActionEvent e) {
synchronized (this) {
flag =true;
String k = t1.getText();
in = k;
t2.setText("Client:"+k);
t1.setText("");
}
}
}
}
接受端Sever端的代码如下:
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class ChatSever extends Frame{
TextField t1;
TextArea t2;
String in;
ChatSever() {
this.setBounds(200, 200, 500, 500);
this.setVisible(true);
this.setResizable(true);
this.setLayout(new BorderLayout ());
t1 = new TextField(10);
t2 = new TextArea();
this.add(t1,BorderLayout.SOUTH);
this.add(t2,BorderLayout.CENTER);
t1.addActionListener(new action());
pack();
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String arg[]) throws Exception {
ChatSever chatsever = new ChatSever();
DatagramSocket ds = new DatagramSocket(6666);
while(true) {
byte buf[] = new byte[1024];
DatagramPacket ps = new DatagramPacket(buf,0,buf.length);
System.out.println("ready");
ds.receive(ps);
ByteArrayInputStream a = new ByteArrayInputStream(buf);
DataInputStream dis = new DataInputStream(a);
String h = dis.readUTF();
System.out.println(h);
chatsever.t2.setText("Client:"+h);
}
}
public class action implements ActionListener {
public void actionPerformed(ActionEvent e) {
String k = t1.getText();
t2.setText("Client:"+k);
t1.setText("");
}
}
}
谢谢各位了,大恩不言谢!!
------解决思路----------------------
1.不会从循环中跳出,按你代码的思路,是判断flag值得真假,来执行不同的逻辑,但始终在循环中。相当于监听线程修改flag,主线程读取flag。
2.监听线程和主线程是独立执行的,不会存在跳出的情况。ActionListener的actionPerformed是一个回调方法,当键盘有输入时,监听线程会调用你的回调方法。ActionListener是监听者模式的用法,你可以自己找相关资料看看。