Dúvida c/ Socket: pq esse código não quer funcionar?

7 respostas
tiagomac

Olá pessoal,
Lá vou eu com mais um probleminha pra ver se vcs podem me socorrer:

to fazendo um experimento com socket em java, para criar apenas um simples programinha de chat. eu criei 3 classes apenas, uma GUI, outra sendo uma thread observable para notificar a GUI que existe novas msgs e uma onde fica o Main que aguarda a conexão e quando estabelecida chama pela GUI. segue o código de cada uma delas abaixo:

Main.java (Client side)
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
//		try {
//	         Socket skt = new Socket("localhost", 1234);
//	         BufferedReader in = new BufferedReader(new
//	            InputStreamReader(skt.getInputStream()));
//	         System.out.print("Received string: '");
//
//	         while (!in.ready()) {}
//	         System.out.println(in.readLine()); // Read one line and output it
//
//	         System.out.print("'\n");
//	         in.close();
//	      }
//	      catch(Exception e) {
//	         System.out.print("Whoops! It didn't work!\n");
//	      }
		//client side
		int port = 4444;
		Socket socket = null;
		try {
			socket = new Socket("127.0.0.1", port);
			if (socket != null){
				GUI gui = new GUI(socket);
				gui.setVisible(true);
			}
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}



	}

}
GUI.java (Both)
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Observable;
import java.util.Observer;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class GUI extends JFrame implements Observer {

	private static final long serialVersionUID = 1L;

	private JPanel jContentPane = null;

	private JPanel jPanel_conteudo = null;

	private JTextArea jTextArea_msgR = null;

	private JTextArea jTextArea_msgS = null;

	private JButton jButton_enviar = null;

//	extra fields
	Socket socket = null;
	MsgReceiver msgReceiver = null;
	PrintWriter out = null;
	/**
	 * This is the default constructor
	 */
	public GUI(Socket socket) {
		super();
		this.socket = socket;
		try {
			this.out = new PrintWriter(this.socket.getOutputStream(), true);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		msgReceiver = new MsgReceiver(this, this.socket);
		Thread thMsgReceiver = new Thread(msgReceiver);
		initialize();
		thMsgReceiver.start();
	}

	/**
	 * This method initializes this
	 *
	 * @return void
	 */
	private void initialize() {
		this.setSize(406, 240);
		this.setContentPane(getJContentPane());
		this.setTitle("Chat - Client");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.addWindowListener(new java.awt.event.WindowAdapter() {
			public void windowClosing(java.awt.event.WindowEvent e) {
				terminar();
			}
		});
		this.pack();
		this.setLocationRelativeTo(null);
	}

	/**
	 * This method initializes jContentPane
	 *
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(new GridBagLayout());
			jContentPane.add(getJPanel_conteudo(), new GridBagConstraints(0,0,1,1,1.0d,1.0d,GridBagConstraints.CENTER, GridBagConstraints.BOTH, (new Insets(8,8,8,8)),0,0 ));
		}
		return jContentPane;
	}

	/**
	 * This method initializes jPanel_conteudo
	 *
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanel_conteudo() {
		if (jPanel_conteudo == null) {
			jPanel_conteudo = new JPanel();
			jPanel_conteudo.setLayout(new GridBagLayout());
			jPanel_conteudo.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.black));
			jPanel_conteudo.add(getJTextArea_msgR(), new GridBagConstraints(0,0,2,1,1.0d,1.0d,GridBagConstraints.CENTER,GridBagConstraints.BOTH,(new Insets(0,0,5,0)),0,0));
			jPanel_conteudo.add(getJTextArea_msgS(), new GridBagConstraints(0,1,1,1,0.8d,0.5d,GridBagConstraints.CENTER,GridBagConstraints.BOTH,(new Insets(0,0,0,0)),0,0));
			jPanel_conteudo.add(getJButton_enviar(), new GridBagConstraints(1,1,1,1,0.5d,0.5d,GridBagConstraints.LAST_LINE_END,GridBagConstraints.HORIZONTAL,(new Insets(0,0,0,0)),0,0));
		}
		return jPanel_conteudo;
	}

	/**
	 * This method initializes jTextArea_msgR
	 *
	 * @return javax.swing.JTextArea
	 */
	private JTextArea getJTextArea_msgR() {
		if (jTextArea_msgR == null) {
			jTextArea_msgR = new JTextArea();
			jTextArea_msgR.setPreferredSize(new Dimension(340, 180));
		}
		return jTextArea_msgR;
	}

	/**
	 * This method initializes jTextArea_msgS
	 *
	 * @return javax.swing.JTextArea
	 */
	private JTextArea getJTextArea_msgS() {
		if (jTextArea_msgS == null) {
			jTextArea_msgS = new JTextArea();
			jTextArea_msgS.setPreferredSize(new Dimension(240, 120));
		}
		return jTextArea_msgS;
	}

	/**
	 * This method initializes jButton_enviar
	 *
	 * @return javax.swing.JButton
	 */
	private JButton getJButton_enviar() {
		if (jButton_enviar == null) {
			jButton_enviar = new JButton();
			jButton_enviar.setText("Enviar");
			jButton_enviar.setPreferredSize(new Dimension(40, 40));
			jButton_enviar.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					System.out.println("botao clicado");
					out.print((String)(jTextArea_msgS.getText()));
				}
			});
		}
		return jButton_enviar;
	}

	public void update(Observable o, Object arg) {
		jTextArea_msgR.append(arg.toString());
		System.out.println(arg);
	}
	private void terminar(){
		msgReceiver.terminar();
		try {
			this.socket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}  //  @jve:decl-index=0:visual-constraint="10,10"
MsgReceiver (Both)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.Observable;
import java.util.Observer;


public class MsgReceiver extends Observable implements Runnable {
	BufferedReader in = null;
	String novaLinha;
	volatile boolean continua = true;
	Socket socket = null;
	public MsgReceiver(Observer ob, Socket socket){
		this.socket = socket;
		try {
			this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
		} catch (IOException e) {
			e.printStackTrace();
		}
		addObserver(ob);
	}
	public void run(){
		while (continua){
			if (!this.socket.isConnected()){
				try {
					if (this.socket != null)
						this.socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				terminar();
			}
			try {
				while (in.ready()){
					System.out.println("recebeu msg:");
					novaLinha = in.readLine();
					System.out.println(novaLinha);
					notifyObservers(novaLinha);
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public void terminar(){
		try {
			in.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		continua = false;
	}
}
Main.java (Server side)
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
//	      String data = "Toobie ornaught toobie";
//	      try {
//	         ServerSocket srvr = new ServerSocket(1234);
//	         Socket skt = srvr.accept();
//	         System.out.print("Server has connected!\n");
//	         PrintWriter out = new PrintWriter(skt.getOutputStream(), true);
//	         System.out.print("Sending string: '" + data + "'\n");
//	         out.print(data);
//	         out.close();
//	         skt.close();
//	         srvr.close();
//	      }
//	      catch(Exception e) {
//	         System.out.print("Whoops! It didn't work!\n");
//	      }
		//client side
		int port = 4444;
		Socket socket = null;
		ServerSocket sSocket = null;
		try {
			sSocket = new ServerSocket(port);
			socket = sSocket.accept();
			if (socket != null){
				GUI gui = new GUI(socket);
				gui.setVisible(true);
			}
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}



	}

}

como vocês podem ver, a única diferença entre o client e o servidor é no Main.java...

Eu queria entender pq não está funcionando, alguém poderia somente explicar o que existe de errado?
ele conecta, abre o GUI, mas não envia nem recebe :/!

vlw a todos e um forte abraço.

7 Respostas

Marky.Vasconcelos

ta certo isso na sua classe Main abri socket em duas portas?

tiagomac

não entendi bem o que vc quis dizer mark, eu acho que vc tá falando da parte do código comentada é isso? bom, a parte q tá comentada foi só um teste para ver se o problema não era comigo (parte física) pois peguei ele na net e funcionou corretamente… o código (não comentado) que não tá funcionando :(!

tiagomac

Olá pessoal,

novamente aqui, persistindo no assunto… é que tentei novamente trabalhar em cima desse código e não obtive resultados. eu posso utilizar o getInputStream c/ um outputStream ativo?

Se alguém poder me ajudar serei muito grato, to tendo essa difículdade que sei que é algo até simples de ser feito em java, mas o que deveria funcionar na teoria, comigo não tá indo na prática, sei que existe algum erro no código, só não localizo onde :(!

forte abraço a todos.

Marky.Vasconcelos

Por partes
Você cria o server chama o GUI com o server.accept()
GUI abre OutputStream com o getOutputStream do socket
GUI chama MsgReciver ela abre o Input com o Input do socket

no client chama o GUI com o socket
o GUI tenta pega o Outputstream ao mesmo tempo que o GUI do server espera o Out desse
solução
pode cria dois tipos de GUI e dois Receiver
um pro server e outor pro cliente
só que o do cliente primeiro pega o InputStream
e depois o OutputStream
enquanto o sever o contrario
ou vice-versa^^

uma das Soluções Dai eu fiz essas classe pra ve se te ajuda ServGui.java
import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.Insets;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.Socket;
 import java.util.Observable;
 import java.util.Observer;
 
 import javax.swing.BorderFactory;
 import javax.swing.JButton;
 import javax.swing.JFrame;
 import javax.swing.JPanel;
 import javax.swing.JTextArea;
 
 public class ServGUI extends JFrame implements Observer {
 
 	private static final long serialVersionUID = 1L;
 
 	private JPanel jContentPane = null;
 	private JPanel jPanel_conteudo = null;
 	private JTextArea jTextArea_msgR = null;
 	private JTextArea jTextArea_msgS = null;
 	private JButton jButton_enviar = null;
 
 	Socket socket = null;
 	ServMsgReceiver msgReceiver = null;
 	PrintWriter out = null;
 	
 	public ServGUI(Socket socket) {
 		super("Char - Client");
 		this.socket = socket;
 		try {
 			this.out = new PrintWriter(this.socket.getOutputStream());
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
 		msgReceiver = new ServMsgReceiver(this, this.socket);
 		Thread thMsgReceiver = new Thread(msgReceiver);
 		initialize();
 		thMsgReceiver.start();
 	}
 
 	private void initialize() {
 		setSize(406, 240);
 		setContentPane(getJContentPane());
 		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 		addWindowListener(new java.awt.event.WindowAdapter() {
 			public void windowClosing(java.awt.event.WindowEvent e) {
 				terminar();
 			}
 		});
 		this.pack();
 		this.setLocationRelativeTo(null);
 	}
 
 	private JPanel getJContentPane() {
 		if (jContentPane == null) {
 			jContentPane = new JPanel();
 			jContentPane.setLayout(new GridBagLayout());
 			jContentPane.add(getJPanel_conteudo(), new GridBagConstraints(0,0,1,1,1.0d,1.0d,GridBagConstraints.CENTER, GridBagConstraints.BOTH, (new Insets(8,8,8,8)),0,0 ));
 		}
 		return jContentPane;
 	}

 	private JPanel getJPanel_conteudo() {
 		if (jPanel_conteudo == null) {
 			jPanel_conteudo = new JPanel();
 			jPanel_conteudo.setLayout(new GridBagLayout());
 			jPanel_conteudo.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.black));
 			jPanel_conteudo.add(getJTextArea_msgR(), new GridBagConstraints(0,0,2,1,1.0d,1.0d,GridBagConstraints.CENTER,GridBagConstraints.BOTH,(new Insets(0,0,5,0)),0,0));
 			jPanel_conteudo.add(getJTextArea_msgS(), new GridBagConstraints(0,1,1,1,0.8d,0.5d,GridBagConstraints.CENTER,GridBagConstraints.BOTH,(new Insets(0,0,0,0)),0,0));
 			jPanel_conteudo.add(getJButton_enviar(), new GridBagConstraints(1,1,1,1,0.5d,0.5d,GridBagConstraints.LAST_LINE_END,GridBagConstraints.HORIZONTAL,(new Insets(0,0,0,0)),0,0));
 		}
 		return jPanel_conteudo;
 	}

 	private JTextArea getJTextArea_msgR() {
 		if (jTextArea_msgR == null) {
 			jTextArea_msgR = new JTextArea();
 			jTextArea_msgR.setPreferredSize(new Dimension(340, 180));
 		}
 		return jTextArea_msgR;
 	}

 	private JTextArea getJTextArea_msgS() {
 		if (jTextArea_msgS == null) {
 			jTextArea_msgS = new JTextArea();
 			jTextArea_msgS.setPreferredSize(new Dimension(240, 120));
 		}
 		return jTextArea_msgS;
 	}

 	private JButton getJButton_enviar() {
 		if (jButton_enviar == null) {
 			jButton_enviar = new JButton();
 			jButton_enviar.setText("Enviar");
 			jButton_enviar.setPreferredSize(new Dimension(40, 40));
 			jButton_enviar.addActionListener(new java.awt.event.ActionListener() {
 				public void actionPerformed(java.awt.event.ActionEvent e) {
 					System.out.println("botao clicado");
 					out.print((String)(jTextArea_msgS.getText()));
 				}
 			});
 		}
 		return jButton_enviar;
 	}
 
 	public void update(Observable o, Object arg) {
 		jTextArea_msgR.append(arg.toString());
 		System.out.println(arg);
 	}
 	private void terminar(){
 		msgReceiver.terminar();
 		try {
 			this.socket.close();
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
 
 	}
 
 }
ServMsgReceiver.java
import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.Socket;
 import java.util.Observable;
 import java.util.Observer;
 
 
 public class ServMsgReceiver extends Observable implements Runnable {
 	BufferedReader in = null;
 	String novaLinha;
 	volatile boolean continua = true;
 	Socket socket = null;
 	public ServMsgReceiver(Observer ob, Socket socket){
 		this.socket = socket;
 		try {
 			this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
 		addObserver(ob);
 	}
 	public void run(){
 		while (continua){
 			if (!this.socket.isConnected()){
 				try {
 					if (this.socket != null)
 						this.socket.close();
 				} catch (IOException e) {
 					e.printStackTrace();
 				}
 				terminar();
 			}
 			try {
 				while (in.ready()){
 					System.out.println("recebeu msg:");
 					novaLinha = in.readLine();
 					System.out.println(novaLinha);
 					notifyObservers(novaLinha);
 				}
 			} catch (IOException e) {
 				e.printStackTrace();
 			}
 			try {
 				Thread.sleep(10);
 			} catch (InterruptedException e) {
 				e.printStackTrace();
 			}
 		}
 	}
 	public void terminar(){
 		try {
 			in.close();
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
 		continua = false;
 	}
 }
GUI.java
import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.Insets;
 import java.io.IOException;
import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.net.Socket;
 import java.util.Observable;
 import java.util.Observer;
 
 import javax.swing.BorderFactory;
 import javax.swing.JButton;
 import javax.swing.JFrame;
 import javax.swing.JPanel;
import javax.swing.JTextArea;
 
 public class GUI extends JFrame implements Observer {
 
 	private static final long serialVersionUID = 1L;
 
 	private JPanel jContentPane = null;
 	private JPanel jPanel_conteudo = null;
 	private JTextArea jTextArea_msgR = null;
 	private JTextArea jTextArea_msgS = null;
 	private JButton jButton_enviar = null;
 
 	Socket socket = null;
 	MsgReceiver msgReceiver = null;
 	PrintWriter out = null;
 	public void setOutputStream(OutputStream st){this.out = new PrintWriter(st);}
 	public GUI(Socket socket) {
 		super("Char - Client");
 		this.socket = socket;
 		msgReceiver = new MsgReceiver(this, this.socket);
 		Thread thMsgReceiver = new Thread(msgReceiver);
 		initialize();
 		thMsgReceiver.start();
 	}
 
 	private void initialize() {
 		setSize(406, 240);
 		setContentPane(getJContentPane());
 		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 		addWindowListener(new java.awt.event.WindowAdapter() {
 			public void windowClosing(java.awt.event.WindowEvent e) {
 				terminar();
 			}
 		});
 		this.pack();
 		this.setLocationRelativeTo(null);
 	}
 
 	private JPanel getJContentPane() {
 		if (jContentPane == null) {
 			jContentPane = new JPanel();
 			jContentPane.setLayout(new GridBagLayout());
 			jContentPane.add(getJPanel_conteudo(), new GridBagConstraints(0,0,1,1,1.0d,1.0d,GridBagConstraints.CENTER, GridBagConstraints.BOTH, (new Insets(8,8,8,8)),0,0 ));
 		}
 		return jContentPane;
 	}

 	private JPanel getJPanel_conteudo() {
 		if (jPanel_conteudo == null) {
 			jPanel_conteudo = new JPanel();
 			jPanel_conteudo.setLayout(new GridBagLayout());
 			jPanel_conteudo.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.black));
 			jPanel_conteudo.add(getJTextArea_msgR(), new GridBagConstraints(0,0,2,1,1.0d,1.0d,GridBagConstraints.CENTER,GridBagConstraints.BOTH,(new Insets(0,0,5,0)),0,0));
 			jPanel_conteudo.add(getJTextArea_msgS(), new GridBagConstraints(0,1,1,1,0.8d,0.5d,GridBagConstraints.CENTER,GridBagConstraints.BOTH,(new Insets(0,0,0,0)),0,0));
 			jPanel_conteudo.add(getJButton_enviar(), new GridBagConstraints(1,1,1,1,0.5d,0.5d,GridBagConstraints.LAST_LINE_END,GridBagConstraints.HORIZONTAL,(new Insets(0,0,0,0)),0,0));
 		}
 		return jPanel_conteudo;
 	}

 	private JTextArea getJTextArea_msgR() {
 		if (jTextArea_msgR == null) {
 			jTextArea_msgR = new JTextArea();
 			jTextArea_msgR.setPreferredSize(new Dimension(340, 180));
 		}
 		return jTextArea_msgR;
 	}

 	private JTextArea getJTextArea_msgS() {
 		if (jTextArea_msgS == null) {
 			jTextArea_msgS = new JTextArea();
 			jTextArea_msgS.setPreferredSize(new Dimension(240, 120));
 		}
 		return jTextArea_msgS;
 	}

 	private JButton getJButton_enviar() {
 		if (jButton_enviar == null) {
 			jButton_enviar = new JButton();
 			jButton_enviar.setText("Enviar");
 			jButton_enviar.setPreferredSize(new Dimension(40, 40));
 			jButton_enviar.addActionListener(new java.awt.event.ActionListener() {
 				public void actionPerformed(java.awt.event.ActionEvent e) {
 					System.out.println("botao clicado");
 					out.print((String)(jTextArea_msgS.getText()));
 				}
 			});
 		}
 		return jButton_enviar;
 	}
 
 	public void update(Observable o, Object arg) {
 		jTextArea_msgR.append(arg.toString());
 		System.out.println(arg);
 	}
 	private void terminar(){
 		msgReceiver.terminar();
 		try {
 			this.socket.close();
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
 
 	}
 
 }
MsgReceiver.java
import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.Socket;
 import java.util.Observable;
 
 
 public class MsgReceiver extends Observable implements Runnable {
 	BufferedReader in = null;
 	String novaLinha;
 	volatile boolean continua = true;
 	Socket socket = null;
 	public MsgReceiver(GUI ob, Socket socket){
 		this.socket = socket;
 		try {
 			this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
 			ob.setOutputStream(this.socket.getOutputStream());
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
 		addObserver(ob);
 	}
 	public void run(){
 		while (continua){
 			if (!this.socket.isConnected()){
 				try {
 					if (this.socket != null)
 						this.socket.close();
 				} catch (IOException e) {
 					e.printStackTrace();
 				}
 				terminar();
 			}
 			try {
 				while (in.ready()){
 					System.out.println("recebeu msg:");
 					novaLinha = in.readLine();
 					System.out.println(novaLinha);
 					notifyObservers(novaLinha);
 				}
 			} catch (IOException e) {
 				e.printStackTrace();
 			}
 			try {
 				Thread.sleep(10);
 			} catch (InterruptedException e) {
 				e.printStackTrace();
 			}
 		}
 	}
 	public void terminar(){
 		try {
 			in.close();
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
 		continua = false;
 	}
 }
Main continua o mesmo(o do cliente) já no Server invés de chamar
GUI gui = new GUI(socket.accept());
//use
ServGUI = new ServGUI(socket.accept());
Marky.Vasconcelos

Obs: Rodei os dois digito e envio e só aparece no console

tiagomac

Mark, eu não tive tempo ainda de testar o código em minha máquina pois ainda não configurei o ambiente, tava pensando em testar hj a noite na faculdade.
mas pelo que entende o seu tbm não funcionou? ou funcionou?

Vlw, abração!

Marky.Vasconcelos

Não sei oque era que nun funcionava antes mais agora só aparece Botao clicado quando eu clico no botão
mesmo com uma mensagem escrita

Criado 3 de agosto de 2007
Ultima resposta 9 de ago. de 2007
Respostas 7
Participantes 2