您好我正在使用内部IP网络与java聊天但是我发送了一些消息之后发生了一个错误,这个程序混合了之前的消息和新发送的消息,无法找到它的原因。 遵循代码。
Conexao.java
公共类Conexao扩展了Observable {
private String ip;
private int porta;
private String mensagem;
public Conexao(String ip, int porta) {
this.ip = ip;
this.porta = porta;
new Thread(new Recebe()).start();
}
public String getMensagem() {
return mensagem;
}
public String getIp() {
return ip;
}
public int getPorta() {
return porta;
}
public void envia(String texto) {
new Thread(new Envia(texto)).start();
}
public void notifica(String mensagem) {
this.mensagem = mensagem;
setChanged();
notifyObservers();
}
class Recebe implements Runnable {
byte[] dadosReceber = new byte[65508];
boolean erro = false;
DatagramSocket socket = null;
@Override
public void run() {
while (true) {
try {
socket = new DatagramSocket(getPorta());
} catch (SocketException ex) {
Logger.getLogger(Conexao.class.getName()).log(Level.SEVERE, null, ex);
}
erro = false;
while (!erro) {
DatagramPacket pacoteRecebido = new DatagramPacket(dadosReceber, dadosReceber.length);
try {
socket.receive(pacoteRecebido);
socket.getReceiveBufferSize();
byte[] b = pacoteRecebido.getData();
String s = "";
for (int i = 0; i < b.length; i++) {
if (b[i] != 0) {
s += (char) b[i];
}
}
String nome = pacoteRecebido.getAddress().toString() + " disse:";
notifica(nome + s);
} catch (Exception e) {
System.out.println("erro");
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(Conexao.class.getName()).log(Level.SEVERE, null, ex);
}
erro = true;
}
}
}
}
}
class Envia implements Runnable {
String texto;
public Envia(String texto) {
this.texto = texto;
}
@Override
public void run() {
byte[] dados = texto.getBytes();
try {
DatagramSocket clientSocket = new DatagramSocket();
InetAddress addr = InetAddress.getByName(getIp());
DatagramPacket pacote = new DatagramPacket(dados, dados.length, addr, getPorta());
clientSocket.send(pacote);
clientSocket.close();
} catch (SocketException ex) {
Logger.getLogger(Conexao.class.getName()).log(Level.SEVERE, null, ex);
} catch (UnknownHostException ex) {
Logger.getLogger(Conexao.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Conexao.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
JanelaChat.java
公共类JanelaChat扩展javax.swing.JFrame实现Observer {
private Conexao conexao;
public JanelaChat(Conexao conexao) {
super("chat");
this.conexao = conexao;
initComponents();
conexao.addObserver(this);
escreve("Chat iniciado com " + conexao.getIp() + ":" + conexao.getPorta());
mensagemjTextArea.requestFocusInWindow();
}
private void envia() {
if (!mensagemjTextArea.getText().isEmpty()) {
conexao.envia(mensagemjTextArea.getText());
escreve("Você disse: " + mensagemjTextArea.getText());
mensagemjTextArea.setText("");
}
}
private void escreve(String texto) {
chatjTextArea.append(texto + "\n");
if (!chatjTextArea.getText().isEmpty() && !chatjTextArea.isFocusOwner()) {
chatjTextArea.setCaretPosition(chatjTextArea.getText().length() - 1);
}
}
感谢您的关注,对不起我的英语,我希望我能说清楚。
答案 0 :(得分:0)
您对运输做出了难以理解的假设。 UDP数据报可以多次传送,不按顺序传送,或者根本不传送。如果您需要可靠性,排序,非重复等,请使用TCP。
你还有其他问题。从新接收的数据报构建String的正确方法(假设它只包含字符数据)是:
String s = new String(packet.getData(), packet.getOffset(), packet.getLength());
您不需要所有的空检查:只需要上面的内容。