Socket em janela lembra o msn
Publicado por Abraao dos Santos Carvalho 20/12/2007
[ Hits: 7.678 ]
Esse exemplo foi desenvolvido no netbeans. É um socket servidor e cliente, que envia mensagens de um para o outro, lembra o msn.
A conexão é encerrada quando se digita TERMINATE. Para iniciar, coloque o numero da porta nos dois, e o endereço no cliente(localhost), pode ser endereço ip se for em maquinas diferentes.
Abaixo estão os dois codigos. Caso alguém melhorar mande para mim.
peujrcarvalho@hotmail.com
/* * MsnServidor.java * * Created on 9 de Outubro de 2007, 15:08 */ package Sockets; import java.io.*; import java.net.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * * @author Abraão */ public class MsnServidor extends javax.swing.JFrame { ObjectOutputStream output; ObjectInputStream input; String message; /** Creates new form MsnServidor */ public MsnServidor() { super( "MsnServidor" ); initComponents(); } /** 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. */ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents private void initComponents() { jButton1 = new javax.swing.JButton(); jLabel1 = new javax.swing.JLabel(); jButton2 = new javax.swing.JButton(); jLabel2 = new javax.swing.JLabel(); janela1 = new javax.swing.JTextField(); janela2 = new javax.swing.JTextField(); jScrollPane1 = new javax.swing.JScrollPane(); janela3 = new javax.swing.JTextArea(); jButton4 = new javax.swing.JButton(); janela4 = new javax.swing.JTextField(); jLabel3 = new javax.swing.JLabel(); jLabel4 = new javax.swing.JLabel(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); jButton1.setText("Iniciar"); jButton1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton1ActionPerformed(evt); } }); jLabel1.setText("Receber"); jButton2.setText("Sair"); jButton2.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton2ActionPerformed(evt); } }); jLabel2.setText("Enviar"); janela1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { janela1ActionPerformed(evt); } }); janela2.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { janela2ActionPerformed(evt); } }); janela3.setColumns(20); janela3.setRows(5); janela3.addAncestorListener(new javax.swing.event.AncestorListener() { public void ancestorMoved(javax.swing.event.AncestorEvent evt) { } public void ancestorAdded(javax.swing.event.AncestorEvent evt) { janela3AncestorAdded(evt); } public void ancestorRemoved(javax.swing.event.AncestorEvent evt) { } }); jScrollPane1.setViewportView(janela3); jButton4.setText("Limpar"); jButton4.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton4ActionPerformed(evt); } }); janela4.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { janela4ActionPerformed(evt); } }); jLabel3.setText("Porta"); jLabel4.setText("Status"); org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .addContainerGap() .add(jLabel2)) .add(layout.createSequentialGroup() .add(88, 88, 88) .add(jLabel3) .add(94, 94, 94) .add(jLabel4)) .add(layout.createSequentialGroup() .addContainerGap() .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING) .add(jButton4) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jButton1) .add(layout.createSequentialGroup() .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING) .add(jButton2) .add(jLabel1))))) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false) .add(layout.createSequentialGroup() .add(janela1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 70, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(15, 15, 15) .add(janela2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 299, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 376, Short.MAX_VALUE) .add(janela4)))) .addContainerGap(19, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(jLabel3, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 14, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(jLabel4)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(jButton1) .add(janela1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(janela2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .add(51, 51, 51) .add(jLabel2)) .add(layout.createSequentialGroup() .add(37, 37, 37) .add(janela4, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 59, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))) .add(24, 24, 24) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .add(jLabel1) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 138, Short.MAX_VALUE) .add(jButton4) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(jButton2)) .add(layout.createSequentialGroup() .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 193, Short.MAX_VALUE) .addContainerGap()))) ); pack(); }// </editor-fold>//GEN-END:initComponents private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton4ActionPerformed // TODO add your handling code here: janela4.setText(""); }//GEN-LAST:event_jButton4ActionPerformed private void janela4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_janela4ActionPerformed // TODO add your handling code here: sendData( evt.getActionCommand() ); }//GEN-LAST:event_janela4ActionPerformed private void janela3AncestorAdded(javax.swing.event.AncestorEvent evt) {//GEN-FIRST:event_janela3AncestorAdded // TODO add your handling code here: }//GEN-LAST:event_janela3AncestorAdded private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed // TODO add your handling code here: System.exit(0); }//GEN-LAST:event_jButton2ActionPerformed private void janela1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_janela1ActionPerformed // TODO add your handling code here: }//GEN-LAST:event_janela1ActionPerformed private void janela2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_janela2ActionPerformed // TODO add your handling code here: }//GEN-LAST:event_janela2ActionPerformed private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed // TODO add your handling code here: try { new Thread_espera_conexao("teste").start(); } catch(Exception e) { janela1.setText("Whoops! Problema com o iniciar!\n"); JOptionPane.showMessageDialog(null, "Algum problema com a conexão !!!"); } }//GEN-LAST:event_jButton1ActionPerformed public class Thread_espera_conexao extends Thread { public Thread_espera_conexao(String str) { } public void run() { ServerSocket server; Socket connection; int counter = 1; try { // Step 1: Create a ServerSocket. int nporta = Integer.parseInt(janela1.getText()); server = new ServerSocket( nporta, 100 ); while ( true ) { // Step 2: Wait for a connection. janela2.setText( "Aguardando para conectar\n" ); connection = server.accept(); janela2.setText(""); janela2.setText("Conectado!!!"); janela3.append( "Conexão " + counter + " recebida para: " + connection.getInetAddress().getHostName() ); // Step 3: Get input and output streams. output = new ObjectOutputStream( connection.getOutputStream() ); output.flush(); input = new ObjectInputStream( connection.getInputStream() ); //janela3.append( "\nGot I/O streams\n" ); // Step 4: Process connection. String message = "SERVER>>> Conecção com sucesso"; output.writeObject( message ); output.flush(); janela4.setEnabled( true ); janela4.setText(""); do { try { message = (String) input.readObject(); janela3.append( "\n" + message ); janela3.setCaretPosition(janela3.getText().length());//adicioanei janela3.getText(); } catch ( ClassNotFoundException cnfex ) { janela3.append( "\nUnknown object type received" ); JOptionPane.showMessageDialog(null,"mensagem não enviada!!!"); } } while ( !message.equals( "CLIENT>>> TERMINATE" ) ); // Step 5: Close connection. janela3.append( "\nUser terminated connection" ); output.close(); input.close(); connection.close(); ++counter; } } catch ( EOFException eof ) { System.out.println( "Client terminated connection" ); JOptionPane.showMessageDialog(null,"Fim da CONEXÃO!!!"); } catch ( IOException io ) { io.printStackTrace(); } } } private void sendData( String s ) { try { output.writeObject( "SERVER>>> " + s ); output.flush(); janela3.append( "\nSERVER>>>" + s ); } catch ( IOException cnfex ) { janela3.append( "\nError writing object" ); JOptionPane.showMessageDialog(null,"Erro ao enviar!!!"); } } public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new MsnServidor().setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton jButton1; private javax.swing.JButton jButton2; private javax.swing.JButton jButton4; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel4; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTextField janela1; private javax.swing.JTextField janela2; private javax.swing.JTextArea janela3; private javax.swing.JTextField janela4; // End of variables declaration//GEN-END:variables } /* * MsnCliente.java * * Created on 9 de Outubro de 2007, 15:08 */ package Sockets; import java.io.*; import java.net.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * * @author Abraão */ public class MsnCliente extends javax.swing.JFrame { ObjectOutputStream output; ObjectInputStream input; String message = ""; /** Creates new form MsnCliente */ public MsnCliente() { super( "MsnCliente" ); initComponents(); } /** 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. */ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents private void initComponents() { jButton1 = new javax.swing.JButton(); jLabel1 = new javax.swing.JLabel(); jLabel2 = new javax.swing.JLabel(); jButton2 = new javax.swing.JButton(); jScrollPane1 = new javax.swing.JScrollPane(); janela5 = new javax.swing.JTextArea(); jButton4 = new javax.swing.JButton(); janela1 = new javax.swing.JTextField(); janela3 = new javax.swing.JTextField(); janela4 = new javax.swing.JTextField(); jLabel3 = new javax.swing.JLabel(); janela2 = new javax.swing.JTextField(); jLabel4 = new javax.swing.JLabel(); jLabel5 = new javax.swing.JLabel(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); addComponentListener(new java.awt.event.ComponentAdapter() { public void componentHidden(java.awt.event.ComponentEvent evt) { formComponentHidden(evt); } }); jButton1.setText("Conectar"); jButton1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton1ActionPerformed(evt); } }); jLabel1.setText("Recebido"); jLabel2.setText("Enviar"); jButton2.setText("Sair"); jButton2.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton2ActionPerformed(evt); } }); janela5.setColumns(20); janela5.setRows(5); janela5.addAncestorListener(new javax.swing.event.AncestorListener() { public void ancestorMoved(javax.swing.event.AncestorEvent evt) { } public void ancestorAdded(javax.swing.event.AncestorEvent evt) { janela5AncestorAdded(evt); } public void ancestorRemoved(javax.swing.event.AncestorEvent evt) { } }); jScrollPane1.setViewportView(janela5); jButton4.setText("Limpar"); jButton4.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton4ActionPerformed(evt); } }); janela4.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { janela4ActionPerformed(evt); } }); jLabel3.setText("Porta"); jLabel4.setText("Endere\u00e7o"); jLabel5.setText("Status"); org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .add(94, 94, 94) .add(jLabel3) .add(83, 83, 83) .add(jLabel4)) .add(layout.createSequentialGroup() .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .addContainerGap() .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING) .add(jButton2) .add(layout.createSequentialGroup() .add(jLabel5) .add(13, 13, 13))) .add(jButton4) .add(jLabel1))) .add(jButton1) .add(layout.createSequentialGroup() .addContainerGap() .add(jLabel2))) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() .add(3, 3, 3) .add(janela1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 64, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .add(janela2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 117, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(203, 203, 203)) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false) .add(org.jdesktop.layout.GroupLayout.LEADING, janela3) .add(org.jdesktop.layout.GroupLayout.LEADING, jScrollPane1) .add(org.jdesktop.layout.GroupLayout.LEADING, janela4, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 332, Short.MAX_VALUE))))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(jLabel3) .add(jLabel4)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(jButton1) .add(janela1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(janela2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .add(6, 6, 6) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(jLabel5) .add(janela3, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .add(20, 20, 20) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(jLabel2) .add(janela4, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 51, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .add(20, 20, 20) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() .add(jLabel1) .add(50, 50, 50) .add(jButton4) .add(14, 14, 14) .add(jButton2)) .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 196, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(11, 11, 11))) .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); pack(); }// </editor-fold>//GEN-END:initComponents private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton4ActionPerformed // TODO add your handling code here: janela4.setText(""); }//GEN-LAST:event_jButton4ActionPerformed private void janela4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_janela4ActionPerformed // TODO add your handling code here: sendData( evt.getActionCommand() ); }//GEN-LAST:event_janela4ActionPerformed private void janela5AncestorAdded(javax.swing.event.AncestorEvent evt) {//GEN-FIRST:event_janela5AncestorAdded // TODO add your handling code here: }//GEN-LAST:event_janela5AncestorAdded private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed // TODO add your handling code here: System.exit(0); }//GEN-LAST:event_jButton2ActionPerformed private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed // TODO add your handling code here: try { new Thread_espera_conexao("teste").start(); } catch(Exception e) { janela1.setText("Whoops! Problema com o iniciar!\n"); JOptionPane.showMessageDialog(null, "Algum problema com a conexão !!!"); } }//GEN-LAST:event_jButton1ActionPerformed public class Thread_espera_conexao extends Thread { public Thread_espera_conexao(String str) { } public void run() { Socket client; try { int nporta = Integer.parseInt(janela1.getText()); String end_serv = janela2.getText(); client = new Socket( end_serv , nporta ); janela5.append( "Conectado para: " + client.getInetAddress().getHostName() ); janela2.setText("Conectado!!!"); // Step 2: Get the input and output streams. output = new ObjectOutputStream( client.getOutputStream() ); output.flush(); input = new ObjectInputStream( client.getInputStream() ); //janela5.append( "\nGot I/O streams\n" ); // Step 3: Process connection. janela4.setEnabled( true ); do { try { message = (String) input.readObject(); janela5.append( "\n" + message ); janela5.setCaretPosition(janela5.getText().length());//adicioanei janela5.getText(); } catch ( ClassNotFoundException cnfex ) { janela5.append( "\nUnknown object type received" ); JOptionPane.showMessageDialog(null,"mensagem não enviada!!!"); } } while ( !message.equals( "SERVER>>> TERMINATE" ) ); // Step 4: Close connection. janela5.append( "Closing connection.\n" ); output.close(); input.close(); client.close(); } catch ( EOFException eof ) { System.out.println( "Server terminated connection" ); JOptionPane.showMessageDialog(null,"Fim da CONEXÃO!!!"); } catch ( IOException e ) { e.printStackTrace(); } } } private void sendData( String s ) { try { message = s; output.writeObject( "CLIENT>>> " + s ); output.flush(); janela5.append( "\nCLIENT>>>" + s ); } catch ( IOException cnfex ) { janela5.append( "\nError writing object" ); JOptionPane.showMessageDialog(null,"Erro ao enviar!!!"); } } private void formComponentHidden(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentHidden // TODO add your handling code here: }//GEN-LAST:event_formComponentHidden /** * @param args the command line arguments */ public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new MsnCliente().setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton jButton1; private javax.swing.JButton jButton2; private javax.swing.JButton jButton4; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel4; private javax.swing.JLabel jLabel5; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTextField janela1; private javax.swing.JTextField janela2; private javax.swing.JTextField janela3; private javax.swing.JTextField janela4; private javax.swing.JTextArea janela5; // End of variables declaration//GEN-END:variables }
Um pouco de Java e Sockets. (Fonte 03: Recebedor)
nome para ip & ip para nome com ping
Nome da máquina e o endereço IP sem socket.
Um pouco de Java e Sockets. (Fonte 04: Main)
Título: Descobrindo o IP externo da VPN no Linux
Armazenando a senha de sua carteira Bitcoin de forma segura no Linux
Enviar mensagem ao usuário trabalhando com as opções do php.ini
Encontre seus arquivos facilmente com o Drill
Mouse Logitech MX Ergo Advanced Wireless Trackball no Linux
Compartilhamento de Rede com samba em modo Público/Anônimo de forma simples, rápido e fácil
Cups: Mapear/listar todas as impressoras de outro Servidor CUPS de forma rápida e fácil
Alternar as janelas clicando na barra de tarefas (7)
qual tipo de interface linux para processador do tipo apu (9)
Agora temos uma assistente virtual no fórum!!! (244)
Ubuntu 22.04 / Bluethooth - Falha na conexão BlueZ | Não conecta caixa... (6)