2016-04-24 24 views
0

你好,我正在与java使用内部IP网络聊天,但我发送一些消息后发生一些错误的程序,这与以前发送的新消息混在一起,无法找到原因。 遵循代码。Java Socket混合先前的消息最近的帖子

Conexao.java

公共类登录时间延伸可观察{

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中实现观察{

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

你对你的交通工具做出了无法承受的假设。 UDP数据报可以多次传送,乱序传送,或根本不传送。如果您想要可靠性,排序,不重复等,请使用TCP。

您还有其他问题。正确的方法来从一个新接收到的数据包(假设只包含字符数据)创建一个字符串是:

String s = new String(packet.getData(), packet.getOffset(), packet.getLength()); 

你并不需要所有的空检查:刚才上面。

+0

谢谢帮助挺好的 –