Socket para conexão entre Servidor e vários Clientes.
Estou tentando criar um chat onde os clientes enviam mensagens para o servidor e este mandam as mensagens para todos os clientes.
Problema: quando tenho um único cliente o servidor envia a mensagem corretamente, mas quendo tenho dois clientes e o 1ª envia uma mensagem está vai apenas para o 2ª e não para o 1ª. outro detalhe é que apenas uma mensagem é enviada para o 2ª, quando tento enviar outra ele não vai nem para o 1ª e nem para 2ª.
Gostaria que alguém pudesse mim esclarecer isto, pois estou iniciando no java é tenho muitas dúvidas.
Detalhes: estou usando ObjectOutputStream e ObjectInputStream
Alysson
Curtidas 0
Respostas
Marcos Pereira
09/04/2009
Bom, se o 1º é quem está enviando, faz um pouco de sentido que ele não receba de volta a propria mensagem. No mais, há poucos detalhes para saber qual o seu problema. Está usando sockets tcp ou udp?! Como está o esquema de threads do seu servidor?!
valeuz...
GOSTEI 0
Felt
09/04/2009
pra mim faz sentido quem manda receber a sua mensagem...
mas isso nao importa..
Problema: quando tenho um único cliente o servidor envia a mensagem corretamente, mas quendo tenho dois clientes e o 1ª envia uma mensagem está vai apenas para o 2ª e não para o 1ª. outro detalhe é que apenas uma mensagem é enviada para o 2ª, quando tento enviar outra ele não vai nem para o 1ª e nem para 2ª.
fica dificil responder sem ver o codigo..
GOSTEI 0
Felt
09/04/2009
tb acho que tem que receber... td cliente de chat (IRC, ICQ, MSN, etc) vc ve o que vc falou....
q caos fica falano meia hora com uma pessoa e nao ve suas proprias falas.... eu ficaria meio perdido....
;)
td mundo que manda tb recebe.... seria algo assim.... vc manda a mensagem pro servidor, q manda para TODO mundo.... no caso de ser uma msg privada, o servidor envia para quem mandou e quem recebe..
Realmente... sem o cod. fica dificil... =(
GOSTEI 0
Diego Fronza
09/04/2009
Ae amigo, eu fiz um chat interno da empresa onde trabalho e depois de vários testes com ObjectInputStream e ObjectOutputStream percebi que eles não funcionavam como eu esperava, então passei a usar DataInputStream para ler e PrintWriter para escrever no socket.
O Eskema que utilizei no chat é o seguinte, criei uma classe usuário, que armazenava dentro dela o socket do usuario, nick etc... cada vez que um cliente se conectava eu coletava essas informacoes e armazenava numa LinkedList um Object Usuario, dessa forma quando uma nova mensagem chegava tudo que tinha que fazer era varrer a LinkedList com Iterator e enviar a mensagem para os demais clientes.
Se quiser posso lhe enviar o chat, mas faz tempo que não dou manutenção dele, ele tem interface gráfica e é acompanhado de um Servidor que pode chutar ou não os usuarios.
diego@exactus.com.br
GOSTEI 0
Felt
09/04/2009
Galera, aí vai o código do meu servidor. Lembrando que, com um usuário ele responde a todas mensagens enviadas. O problema é quando tem mais de um usuário ele não envia a mensagem para todos.
Obrigado pela ajuda.
public class Teste {
private ObjectOutputStream output;
private ObjectInputStream input;
private ServerSocket server;
private Socket connection;
public Teste() {
try {
server = new ServerSocket( 5000 );
while ( true ) {
System.out.println( "Aguardando conexão ..." );
connection = server.accept();
System.out.println( connection.getInetAddress().getHostName() );
ThreadServer ts = new ThreadServer();
ts.start();
}
}
catch ( EOFException eofException ) {
System.out.println( "Cliente fechou conexão." );
}
catch ( IOException ioException ) {
ioException.printStackTrace();
}
}
public class ThreadServer extends Thread {
public void run() {
try {
output = new ObjectOutputStream( connection.getOutputStream() );
input = new ObjectInputStream(connection.getInputStream() );
ProcessaConexao();
closeConnection();
}
catch (IOException ex) {
}
}
}
private void ProcessaConexao() throws IOException
{
String message = "Conectado";
output.writeObject( message );
while (true) {
try {
message = ( String ) input.readObject();
output.writeObject( message );
}
catch ( ClassNotFoundException classNotFoundException ) {
}
}
}
private void closeConnection() throws IOException {
output.close();
input.close();
connection.close();
}
public static void main( String args[] )
{
Teste app = new Teste();
}
}
GOSTEI 0
Felt
09/04/2009
alysson
vc tem de alguma forma guardar a referencia para todos os clientes que estao no chat em um certo momento..
assim que alguem manda um objeto mensagem, vc tem q repassar para todos os clientes conectados atraves do output de cada cliente
vc mantem apenas 1 referencia de input e output.. no caso vc tem q ter 1 input e 1 output para cada cliente conectado...
como o avenger falou, vc pode ter uma classe Client que guarda o socket, o input e output de 1 determinado cliente.. o seu thread deve conhecer apenas 1 cliente.. quando ele receber uma informacao, ele varre uma lista de clientes e escreve nos outputs deles..
nao sei se fico mto confuso.. qq coisa pergunta...
GOSTEI 0
Felt
09/04/2009
Galera já consegui. Desde já quero agradecer a todos pela ajuda. :o
GOSTEI 0
Felt
09/04/2009
[quote="alysson"]Galera já consegui. Desde já quero agradecer a todos pela ajuda. :o
Que tal colocar a solucao para todo mundo aqui?
:!: :!:
GOSTEI 0
Felt
09/04/2009
Boa noite amigos,to fazendo um chat aqui e to com dificuldade pra mandar a mensagem somente pra um cliente.
public class Servidor {
public static void main(String [] args) throws IOException {
//inicia o servidor
new Servidor(12345).executa();
}
private int porta;
private boolean encerrar;
private List<PrintStream> clientes;
public Servidor (int porta) {
this.porta = porta;
this.clientes = new ArrayList<PrintStream>();
}
public void executa () throws IOException {
ServerSocket servidor = new ServerSocket(this.porta);
System.out.println("Porta 12345 aberta!");
while (!encerrar){
//aceita um cliente
Socket cliente = servidor.accept();
System.out.println("Nova conexao com o cliente" +
cliente.getInetAddress().getHostAddress());
//adiciona saida do cliente à lista
PrintStream ps = new PrintStream(cliente.getOutputStream());
this.clientes.add(ps);
//cria tratador de cliente numa nova tread
TrataCliente tc = new TrataCliente(cliente.getInputStream(),this);
new Thread(tc).start();
}
}
public void distribuiMensagem(String msg) {
((PrintStream) this.clientes).println(msg);
}
public class TrataCliente implements Runnable {
private InputStream cliente;
private Servidor servidor;
public TrataCliente(InputStream cliente,Servidor servidor){
this.cliente = cliente;
this.servidor = servidor;
}
public void run() {
//quando chegar uma msg distribui pra todos
Scanner s = new Scanner(this.cliente);
while (s.hasNextLine()) {
servidor.distribuiMensagem(s.nextLine());
}
s.close();
}
}
}
GOSTEI 0
Felt
09/04/2009
[quote="loverboy"]Boa noite amigos,to fazendo um chat aqui e to com dificuldade pra mandar a mensagem somente pra um cliente.
muito interessante, o fato de voce ter dificuldade... mas será que podemos ajudar?
pelo código imagino que não está conseguindo mandar mensagem alguma.
public class Servidor {
public static void main(String [] args) throws IOException {
//inicia o servidor
new Servidor(12345).executa();
}
private int porta;
private boolean encerrar;
private List<PrintStream> clientes;
public Servidor (int porta) {
this.porta = porta;
this.clientes = new ArrayList<PrintStream>();
}
public void executa () throws IOException {
ServerSocket servidor = new ServerSocket(this.porta);
System.out.println("Porta 12345 aberta!");
while (!encerrar){
//aceita um cliente
Socket cliente = servidor.accept();
System.out.println("Nova conexao com o cliente" +
cliente.getInetAddress().getHostAddress());
//adiciona saida do cliente à lista
PrintStream ps = new PrintStream(cliente.getOutputStream());
this.clientes.add(ps);
//cria tratador de cliente numa nova tread
TrataCliente tc = new TrataCliente(cliente.getInputStream(),this);
new Thread(tc).start();
}
}
public void distribuiMensagem(String msg) {
((PrintStream) this.clientes).println(msg);
}
public class TrataCliente implements Runnable {
private InputStream cliente;
private Servidor servidor;
public TrataCliente(InputStream cliente,Servidor servidor){
this.cliente = cliente;
this.servidor = servidor;
}
public void run() {
//quando chegar uma msg distribui pra todos
Scanner s = new Scanner(this.cliente);
while (s.hasNextLine()) {
servidor.distribuiMensagem(s.nextLine());
}
s.close();
}
}
}
((PrintStream) this.clientes).println(msg);
for (PrintStream out : this.clientes) {
out.println(msg);
}
GOSTEI 0
Felt
09/04/2009
então amigão valeu pela dica la, vou quebrar a cabeça lá ,então é exatamente esse codigo de mandar a menssagem pra todos que eu apaguei pra tentar fazer o envio de mensagem só pra uma pessoa, to tentando fazer essa implementação lá
GOSTEI 0
Felt
09/04/2009
public class TrataCliente implements Runnable {
private InputStream cliente;
private Servidor servidor;
private List<PrintStream> clientes;
public TrataCliente(InputStream cliente,Servidor servidor,List<PrintStream> clientes){
this.cliente = cliente;
this.servidor = servidor;
this.clientes = clientes;
public void distribuiMensagem(String msg) {
clientes[].println(msg);
}
}GOSTEI 0
Felt
09/04/2009
então cara esse out que vc colocou ai por acaso ele é um index ? se for como eu pego o indice sem ta utilizando o for pq se eu souber ja resolvo o problema de mandar a mensagem ai vai faltar arrumar o trata cliente
GOSTEI 0
Felt
09/04/2009
[quote="loverboy"]
então Amigão,sua dica me fez pensar um pouco a respeito do código mas acho que ainda to longe da solução, da uma sacada pra ver se eu to pensando certo,ja tirei duvidas importantes em forum e acredito que alguem saiba e possa me ajudar,pois ha sempre os que vão na frente e os bons de coração se algue puder me ajudar ai galera desde ja agradeço a boa vontade
Na verdade esse out é tipo um printwriter, vamo que vamo galera, logo que descobrir a solucão posto o codigo resolvido abraço
public class TrataCliente implements Runnable {
private InputStream cliente;
private Servidor servidor;
private List<PrintStream> clientes;
public TrataCliente(InputStream cliente,Servidor servidor,List<PrintStream> clientes){
this.cliente = cliente;
this.servidor = servidor;
this.clientes = clientes;
public void distribuiMensagem(String msg) {
clientes[].println(msg);
}
}GOSTEI 0
Felt
09/04/2009
[quote="loverboy"][quote="loverboy"]
então Amigão,sua dica me fez pensar um pouco a respeito do código mas acho que ainda to longe da solução, da uma sacada pra ver se eu to pensando certo,ja tirei duvidas importantes em forum e acredito que alguem saiba e possa me ajudar,pois ha sempre os que vão na frente e os bons de coração se algue puder me ajudar ai galera desde ja agradeço a boa vontade
Na verdade esse out é tipo um printwriter, vamo que vamo galera, logo que descobrir a solucão posto o codigo resolvido abraço
assim ta um pouquinho melhor acredito,mas ainda não é isso, ta dando erro no codigo, alguem pode me dar uma luz por favor
public class TrataCliente implements Runnable {
private InputStream cliente;
private Servidor servidor;
private List<PrintStream> clientes;
public TrataCliente(InputStream cliente,Servidor servidor,List<PrintStream> clientes){
this.cliente = cliente;
this.servidor = servidor;
this.clientes = clientes;
public void distribuiMensagem(String msg) {
clientes[].println(msg);
}
} public class TrataCliente implements Runnable {
private InputStream cliente;
private Servidor servidor;
private List<PrintStream> clientes;
public TrataCliente(InputStream cliente,Servidor servidor,List<PrintStream> clientes){
this.cliente = cliente;
this.servidor = servidor;
this.clientes = clientes;
PrintWriter out = null;
out = new PrintWriter(cliente.getOutputStream(), true);
public void distribuiMensagem(String msg) {
out.println(msg);
}
}GOSTEI 0
Felt
09/04/2009
[quote="loverboy"][quote="loverboy"][quote="loverboy"]
então Amigão,sua dica me fez pensar um pouco a respeito do código mas acho que ainda to longe da solução, da uma sacada pra ver se eu to pensando certo,ja tirei duvidas importantes em forum e acredito que alguem saiba e possa me ajudar,pois ha sempre os que vão na frente e os bons de coração se algue puder me ajudar ai galera desde ja agradeço a boa vontade
Na verdade esse out é tipo um printwriter, vamo que vamo galera, logo que descobrir a solucão posto o codigo resolvido abraço
assim ta um pouquinho melhor acredito,mas ainda não é isso, ta dando erro no codigo, alguem pode me dar uma luz por favor
A minha ideia era que cada cliente tivesse a sua saida própria, e não a saida de todos os clientes. Algo assim:
public class TrataCliente implements Runnable {
private InputStream cliente;
private Servidor servidor;
private List<PrintStream> clientes;
public TrataCliente(InputStream cliente,Servidor servidor,List<PrintStream> clientes){
this.cliente = cliente;
this.servidor = servidor;
this.clientes = clientes;
public void distribuiMensagem(String msg) {
clientes[].println(msg);
}
} public class TrataCliente implements Runnable {
private InputStream cliente;
private Servidor servidor;
private List<PrintStream> clientes;
public TrataCliente(InputStream cliente,Servidor servidor,List<PrintStream> clientes){
this.cliente = cliente;
this.servidor = servidor;
this.clientes = clientes;
PrintWriter out = null;
out = new PrintWriter(cliente.getOutputStream(), true);
public void distribuiMensagem(String msg) {
out.println(msg);
}
}public class TrataCliente implements Runnable {
private InputStream entrada;
private PrintStream saida;
private Servidor servidor;
public TrataCliente(InputStream entrada, PrintStream saida, Servidor servidor) {
this.entrada = entrada;
this.saida = saida;
this.servidor = servidor;
}
public void distribuiMensagem(String msg) {
saida.println(msg);
}
}GOSTEI 0