2016-04-24 63 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

謝謝幫助挺好的 –