Socket

8 respostas
T

Ola pessoal tenho um problema aqui.

Estou fazendo um programa cliente servidor (sockets) onde é possive através da GUI entrar com informações (antes de conectar) como o número da porta etc.
Minha ideia é: depois que a pessoa entrar com os dados da porta é só apertar o botão conectar e ele tenta fazer a conexão.
Porém quando faço isso todas as outras funcionalidades da GUI não funcionam devido a linha (connection = server.accept(); ), na qual ele fica esperando uma conexão.

Nenhuma outra funcionalidade da GUI funciona nem o ‘x’ no canto da tela, tenho que matar o processo para fechar o programa.
Alguem pode me ajudar?
Desde já muito obrigado.

8 Respostas

ViniGodoy

Faça sua conexão numa Thread separada.

T

Ola. Obrigado por Responder.
Eu tenho mesmo que criar um outra Thread?

Por que o que eu preciso fazer não exige multiplas-Threads não.
Este é a única solução?

gqferreira

Uma Thread é uma pilha de processos, então, por padrão quando sua aplicação se inicia já esta correndo uma Thread, a principal. Se você chama um metódo que não tem tempo para acabar, ela pára a sua Thread principal, ou seja, o seu aplicativo. A conexão socket vai ficar [color=#ccc]aberta o tempo todo¹[/color] ou [color=red]abre, transmite e fecha²[/color]?

Das duas formas o ideal é trabalhar com uma segunda Thread ou mais mas no primeiro caso é obrigatório, fato!

T

A conexão deve ficar aberta. Eu tenho um botão ‘Desconectar’ que deveria cancelar a conexão com o cliente
porém eu não posso fazer nada nos componentes da GUI devido os problemas acima.

gqferreira

Então você vai precisar criar uma thread mesmo. Não tem como evitar…

T

Ai ta um exemplo do que acontece quando clica no botão conectar. Nada funciona.

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Server.java
 *
 * Created on 27/12/2011, 21:57:17
 */

package Servidor;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
/**
 *
 * @author Mydy
 */
public class Server extends javax.swing.JFrame {

    /** Creates new form Server */
    public Server() {
        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.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();
        ConectButton = new javax.swing.JButton();
        DesconectButton = new javax.swing.JButton();
        porta = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

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

        ConectButton.setText("Conectar");
        ConectButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ConectButtonActionPerformed(evt);
            }
        });

        DesconectButton.setText("Desconectar");
        DesconectButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DesconectButtonActionPerformed(evt);
            }
        });

        porta.setText("1234");

        jLabel1.setText("Porta");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(93, 93, 93)
                .addComponent(ConectButton)
                .addGap(51, 51, 51)
                .addComponent(DesconectButton)
                .addGap(86, 86, 86))
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(porta, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(292, Short.MAX_VALUE))
            .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(porta, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(ConectButton)
                    .addComponent(DesconectButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 169, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

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

    private void ConectButtonActionPerformed(java.awt.event.ActionEvent evt) {
        conectar();
    }

    private void DesconectButtonActionPerformed(java.awt.event.ActionEvent evt) {
        // TODO add your handling code here:
    }

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Server().setVisible(true);
            }
        });
    }

    public void conectar() {
    try {
        ServerSocket server = new ServerSocket( Integer.parseInt(porta.getText()));

        Socket socket = server.accept();

        DataInputStream dis = new DataInputStream
        (socket.getInputStream());

        DataOutputStream dos = new DataOutputStream
        (socket.getOutputStream());

        String mensagem = dis.readUTF();

        System.out.println("Servidor: Mensagem recebida => \"" + mensagem + "\"");

        mensagem = "Mensagem recebida com sucesso às " + new Date();

        System.out.println("Servidor: Mensagem enviada =>  \"" + mensagem + "\"");

        dos.writeUTF(mensagem);

        dis.close();

        dos.close();

        socket.close();

        server.close();
        } catch (Exception ex) {
            /* tratar exceção */
        }
    }

    // Variables declaration - do not modify
    private javax.swing.JButton ConectButton;
    private javax.swing.JButton DesconectButton;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JTextField porta;
    // End of variables declaration

}
gqferreira
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Server.java
 *
 * Created on 27/12/2011, 21:57:17
 */

package main;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
/**
 *
 * @author Mydy
 */
public class Server extends javax.swing.JFrame {

	private Thread xuxuComMel;
	ServerSocket server;	
	Socket socket;
	DataInputStream dis;
	DataOutputStream dos;

	/** Creates new form Server */
	public Server() {
		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.
	 */
	@SuppressWarnings("unchecked")
	// <editor-fold defaultstate="collapsed" desc="Generated Code">
	private void initComponents() {

		jScrollPane1 = new javax.swing.JScrollPane();
		jTextArea1 = new javax.swing.JTextArea();
		ConectButton = new javax.swing.JButton();
		DesconectButton = new javax.swing.JButton();
		porta = new javax.swing.JTextField();
		jLabel1 = new javax.swing.JLabel();

		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

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

		ConectButton.setText("Conectar");
		ConectButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				ConectButtonActionPerformed(evt);
			}
		});

		DesconectButton.setText("Desconectar");
		DesconectButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				DesconectButtonActionPerformed(evt);
			}
		});

		porta.setText("1234");

		jLabel1.setText("Porta");

		javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
		getContentPane().setLayout(layout);
		layout.setHorizontalGroup(
				layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(layout.createSequentialGroup()
						.addGap(93, 93, 93)
						.addComponent(ConectButton)
						.addGap(51, 51, 51)
						.addComponent(DesconectButton)
						.addGap(86, 86, 86))
						.addGroup(layout.createSequentialGroup()
								.addContainerGap()
								.addComponent(jLabel1)
								.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
								.addComponent(porta, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE)
								.addContainerGap(292, Short.MAX_VALUE))
								.addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
		);
		layout.setVerticalGroup(
				layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
						.addContainerGap()
						.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
								.addComponent(jLabel1)
								.addComponent(porta, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
								.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
								.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
										.addComponent(ConectButton)
										.addComponent(DesconectButton))
										.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 169, javax.swing.GroupLayout.PREFERRED_SIZE))
		);

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

	private void ConectButtonActionPerformed(java.awt.event.ActionEvent evt) {
		conectar();
	}

	private void DesconectButtonActionPerformed(java.awt.event.ActionEvent evt) {
		desconectar();
	}

	/**
	 * @param args the command line arguments
	 */
	public static void main(String args[]) {
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				new Server().setVisible(true);
			}
		});
	}

	public void desconectar(){
		try{
			
			if (dis != null)
			dis.close();

			if (dos != null)
			dos.close();

			if (socket != null)
			socket.close();

			server.close();			
			
			xuxuComMel.interrupt();
			ConectButton.setEnabled(true);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void conectar() {

		xuxuComMel = new Thread(new Runnable() {

			@Override
			public void run() {
				try {

					ConectButton.setEnabled(false);

					// TODO Auto-generated method stub
					server = new ServerSocket( Integer.parseInt(porta.getText()));

					socket = server.accept();

					dis = new DataInputStream
					(socket.getInputStream());

					dos = new DataOutputStream
					(socket.getOutputStream());

					String mensagem = dis.readUTF();

					System.out.println("Servidor: Mensagem recebida => \"" + mensagem + "\"");

					mensagem = "Mensagem recebida com sucesso às " + new Date();

					System.out.println("Servidor: Mensagem enviada =>  \"" + mensagem + "\"");

					dos.writeUTF(mensagem);

					dis.close();

					dos.close();

					socket.close();

					server.close();

					ConectButton.setEnabled(true);

				} catch (Exception ex) {
					System.out.println("Conexao quebrada!");
					ConectButton.setEnabled(true);
				}
			}
		});

		xuxuComMel.start();


	}

	// Variables declaration - do not modify
	private javax.swing.JButton ConectButton;
	private javax.swing.JButton DesconectButton;
	private javax.swing.JLabel jLabel1;
	private javax.swing.JScrollPane jScrollPane1;
	private javax.swing.JTextArea jTextArea1;
	private javax.swing.JTextField porta;
	// End of variables declaration

}
ViniGodoy

thalles753:
Ola. Obrigado por Responder.
Eu tenho mesmo que criar um outra Thread?

Existe uma thread que cuida do processamento de eventos e pintura da GUI. Se você travar essa thread num evento, sua GUI nunca vai ser pintada. Seu método accept(), como você mesmo já constatou, não retorna até que a conexão seja feita e, portanto, trava a GUI.

Se você quer duas coisas ao mesmo tempo, ou seja, esperar o accept e ao mesmo tempo processar a GUI, então você precisa sim, de duas threads.

[/quote]Por que o que eu preciso fazer não exige multiplas-Threads não.
Este é a única solução?
[/quote]

Sim. Porque o que você quer, exige sim 2 threads.

Criado 27 de dezembro de 2011
Ultima resposta 28 de dez. de 2011
Respostas 8
Participantes 3