Socket with UTF-8

Asked

Viewed 189 times

0

I’m doing a chat that will run on network (internal), I’m just not able to make work the issue of accents and "ç". It works by running in the IDE but if I have . jar and run (on any PC) it does not work the accents, it gets weird characters.

Chat server

public static void main(String[] args) {
    new ServerChatPologis().initServer();
}

private void initServer() {
    try{
        ServerSocket server = new ServerSocket(PORTA_SERVER);

        //Fica esperando um cliente se conectar
        while(true) {
            Socket cliente = server.accept(); //Aguardando

            //Quando o cliente se conectar
            String ipCliente = cliente.getInetAddress().getHostAddress();
            System.out.println("Efetuada conexão com o endereço " + ipCliente);

            listaClientes.add(new PrintStream(cliente.getOutputStream()));
            listaIps.add(ipCliente);

            //Classe que irá tratar o envio de mensagens do cliente
            TrataCliente trataCliente = new TrataCliente(this, cliente.getInputStream(), ipCliente);
            new Thread(trataCliente).start();

        }

    }catch(Exception ex){
        ex.printStackTrace();
    } 
}

public void mandarMsgParaTodos(String msg) {
    System.out.println(msg);

    for(PrintStream clientStream : listaClientes) {
        clientStream.println(msg);
    }
}

Tratacliente class (who receives the messages and sees what to do).

public class TrataCliente implements Runnable{

    private ServerChatPologis server;
    private InputStream inputClient;
    private String ipCliente;

    public TrataCliente(ServerChatPologis server, InputStream inputClient, String ipCliente) {
        this.server = server;
        this.inputClient = inputClient;
        this.ipCliente = ipCliente;
    }

    public void run() {

        try {

            BufferedReader reader = new BufferedReader(new InputStreamReader(inputClient));

            String msg;
            while ((msg = reader.readLine()) != null) {
                server.mandarMsgParaTodos(msg);
            }

        }catch (Exception e){

        }
    }

}

Swing User Screen for Sending and Receiving Messages. This screen I made just for here, I know it’s not well implemented. But the real one I have has the same shipping and receiving methods, as it is in the codes. I just didn’t put the other one in because it’s bigger than the code.

public class ChatClientSwing2 extends javax.swing.JFrame {

    private Socket cliente;
    private String ipCliente;
    private final String SERVER_ADRESS = "192.168.1.111"; //Aqui na minha rede é usado esse
    private final int PORTA_SERVER = 3225;


    public ChatClientSwing2() {
        initComponents();
        initSocket();
    }

    public void initSocket() {
        try {
            this.cliente = new Socket(SERVER_ADRESS, PORTA_SERVER);
            this.ipCliente = InetAddress.getLocalHost().getHostAddress();

            //Cria Thread que irá receber as mensagens
            initRecebeMsg();

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void initRecebeMsg() {

        //Inicia o recebindo da mensagens
        new Thread() {
            public void run() {
                try {

                    BufferedReader reader = new BufferedReader(new InputStreamReader(cliente.getInputStream(), "UTF-8"));
                    String msg;

                    //Escreve as mensagens recebidas
                    while ((msg = reader.readLine()) != null) {
                        System.out.println(msg);
                        String msgAnterior = areaMensagens.getText();
                        areaMensagens.setText(msgAnterior + "\n" + msg);
                    }

                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }.start();

    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        areaEnviarMensagem = new javax.swing.JTextArea();
        btnEnviar = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        areaMensagens = new javax.swing.JTextArea();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        areaEnviarMensagem.setColumns(20);
        areaEnviarMensagem.setRows(5);
        jScrollPane1.setViewportView(areaEnviarMensagem);

        btnEnviar.setText("Enviar");
        btnEnviar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnEnviarActionPerformed(evt);
            }
        });

        areaMensagens.setColumns(20);
        areaMensagens.setRows(5);
        jScrollPane2.setViewportView(areaMensagens);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane2)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 322, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnEnviar, javax.swing.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                    .addComponent(btnEnviar, javax.swing.GroupLayout.DEFAULT_SIZE, 50, Short.MAX_VALUE))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>                        

    private void btnEnviarActionPerformed(java.awt.event.ActionEvent evt) {                                          

        String msg = areaEnviarMensagem.getText();
        if (msg.isEmpty()) {
            return;
        }

        PrintStream saida = null;
        try {
            saida = new PrintStream(cliente.getOutputStream());
            saida.println(msg);
            areaEnviarMensagem.setText("");
            areaEnviarMensagem.grabFocus();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }                                         

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(ChatClientSwing2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(ChatClientSwing2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(ChatClientSwing2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(ChatClientSwing2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ChatClientSwing2().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JTextArea areaEnviarMensagem;
    private javax.swing.JTextArea areaMensagens;
    private javax.swing.JButton btnEnviar;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    // End of variables declaration                   
}

1 answer

2


It is not in the socket that goes to condification but in the Inputstreamreader and in the Printstream, see the builder:

public InputStreamReader(InputStream in, String charsetName)

In the client chat you put right, but in the Trataclient class missed the utf8:

public void run() {

    try {

        BufferedReader reader = new BufferedReader(new InputStreamReader(inputClient, "UTF-8"));

        String msg;
        while ((msg = reader.readLine()) != null) {
            server.mandarMsgParaTodos(msg);
        }

    }catch (Exception e){

    }
}

Also on the button btnEnviarActionPerformed no charset specified, you can use this constructor:

private void btnEnviarActionPerformed(java.awt.event.ActionEvent evt) {                                          

    String msg = areaEnviarMensagem.getText();
    if (msg.isEmpty()) {
        return;
    }

    PrintStream saida = null;
    try {
        saida = new PrintStream(cliente.getOutputStream(), true, "UTF-8");
        saida.println(msg);
        areaEnviarMensagem.setText("");
        areaEnviarMensagem.grabFocus();
    } catch (IOException ex) {
        ex.printStackTrace();
    }

}  
  • I didn’t understand the Button part, because I couldn’t create this constructor. Even why in the first parameter I am having to pass an Outputstream that is coming from the client (socket).

  • I’m really trying to find a way to do it the way you said but I couldn’t find anything that could make it work

  • I’ll try to be clearer

  • There is no constructor for "output = new Printstream(client.getOutputStream(), "UTF-8");", this is what it shows me when I type in the code passed.

  • In the Java 8 documentation I put in exists, you use java 8?

  • Yes, but in the past documentation there is nothing referring to this constructor, the closest I found was "public Printstream(Outputstream out, Boolean autoFlush, String encoding)", but it also didn’t work :/

  • And besides, running in the IDE even works the way I posted, but if it is run by the generated . jar, not da, it always changes the characters.

  • I actually used this builder that I gave you, this one worked out! Thanks!

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.