Enviar um List através do socket

Pessoal, alguém pode me dizer como eu faço para enviar um List pelo socker??? Estou desenvolvendo uma aplicação de chat com a seguinte situação: o servidor fica operante o tempo todo recebendo cliente, a cada cliente que se conecta a ele, ele obtem o nome e o endereço ip deste cliente, adiciona-o em uma lista em que tem todos os clientes conectados. Logo após ele percorre essa lista que contem todos os clientes e manda para todos a lista de todo mundo com o nome e o ip de todos. Mas não sei como eu faça para enviar essa List para todo mundo, ja que só da a opção de ler String, int, double e etc.

Boa tarde…
Cara, essa semana estava fazendo um projeto para o mestrado aonde era necessário utilizar comunicação dela rede.
O que agente fez foi criar um metodo para transformar um objeto em um array de bytes para enviar e do outro lado criar um metodo para transformar o array de bytes em um objeto.

Espero que ajude

Cara eu fiz algo parecido utilizando RMI.

Atravês de RMI você pode ter um metódo get do seu list ou qualquer outro objeto Serializable, mas ai sua RMI vai ter que o server invocar um método no cliente. Para resolver isso o legal seria que seu client usa-se o padrão Observer, como implementar o Observer ai eu vou esperar alguem mais experiente dar a resposta porque eu também estou interessado.

só um pequeno exemplo. Talvez te ajude:

Servidor:

[code]public class Servidor {
public static void main( String args[] ) {
ServerSocket s = null;
Socket s1;
ObjectOutputStream out;

    List <Integer> lista = new ArrayList<Integer>();
    lista.add(1);
    lista.add(2);
    lista.add(5);
    lista.add(-10);

    try {
        s = new ServerSocket( 4321,300 );
    } catch( IOException e ) {
        System.out.println( e );
    }

    while( true ) {
        try {
            s1 = s.accept();
            out = new ObjectOutputStream(s1.getOutputStream());
	out.writeObject(lista);//passando a lista
            s1.close();
        } catch( IOException e ) {
            System.out.println( e );
            }
        }
    }
}[/code]

Cliente:

[code]
public class Cliente{
public static void main( String args[] ) {
Socket s;
ObjectInputStream in;

    try {
        s = new Socket(InetAddress.getByName("127.0.0.1"),4321 ); //ip , porta
        in= new ObjectInputStream(s.getInputStream());
        List<Integer> lista=(ArrayList<Integer>) in.readObject();//recebendo a lista

        for(int i: lista)
            System.out.println(i);
        
        s.close();

    }
    catch( IOException e ) {
        System.out.println( e );
    }
    catch( ClassNotFoundException e ) {
        System.out.println( e );
    }

}
}[/code]

1 curtida

A implementação do walissongpi é a melhor que existe.

Só acrescento que os objetos dentro da lista devem implementar java.io.Serializable senão vai zicar.
A implementação de List também precisa implementar Serializable, como o ArrayList por exemplo.
map.values() por exemplo não vai rolar.

Exemplo:

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Teste {

public static void main(String args[]) {
	Map<String, String> map = new HashMap<String, String>();
	map.put("1", "1");
	map.put("2", "2");
	map.put("3", "3");
	
	// Isso nao funciona
	Collection<String> c = map.values();
	try {
		Serializable s = (Serializable) c;
	} catch (Exception e) {
		System.out.println("falhou");
		e.printStackTrace();
	}
	
	// Isso funciona
	
	List<String> listaOk = new ArrayList<String>();
	listaOk.addAll(map.values());
	
	try {
		Serializable s = (Serializable) listaOk;
		System.out.println("ok");
	} catch (Exception e) {
		e.printStackTrace();
	}
	
}

}

Isso tudo ta ok, mas como os Clientes vão saber que tem que ler o objeto?

O cliente tem sempre que fazer o in.readObject();
Este método bloqueia a execução até que haja dados disponíveis (enviados pelo servidor).

Deve ser visto a questão de timeout.

De “certa forma” podemos ter um comportamento próximo do pattern Observer. O observer se cadastra como listener do observable. E sempre que o Observable altera seu estado interno, ele faz um loop nos listeners e vai notificando.

O cliente socket ao fazer um readObject(); ele está de certa forma parando sua execução e aguardando informações como se fosse um listener.

Legal,

Então seria melhor colocar isso em uma thread.

Pessoal é o seguinte:

fiz conforme o nosso amigo ai walissongpi postou. No servidor beleza, compilei e não deu erro. Porém no cliente eu clio uma List do tipo cliente, mas o compilador diz que não tem uma classe do tipo cliente como vai ficar. Vejam abaixo meu código no lado cliente:

List clientes = entrada.readObject();

ai o compilador diz que não tem uma classe chamada cliente.

Será que o tipo da lista não pode ser cliente, tem que ser de outro jeito??? alguém pode me ajudar???

Então, este objeto Cliente seu seria tipo um Value Object. Ele deve ser visivel tanto no projeto cliente como no projeto servidor.

A classe Cliente deve ser incluida no classpath do servidor e do projeto cliente tb …

então CarvalR2 infelizmente eu não sei fazer isso e, não sei se é pedir demais, será que vc pode me dar uma forcinha de como fazer isso??

Você está utilizando o eclipse ou netbeans?
Você tem um projeto para o software servidor e outro para o software cliente do chat? Ou está tudo em um projeto apenas?

Bom. Esta tudo em um projeto só mas logo irei colocar o servidor num projeto, e o cliente em outro para gera o jar separados, quanto a ide, estou utilizando o netbeans.

Então, você terá de criar um 3o projeto com classes comuns aos dois projetos.
Este 3o projeto gera como produto final um arquivo jar. Por exemplo: classescomuns.jar

Este classescomuns.jar você colocará como lib do projeto de software Servidor e do projeto de software Cliente.

Este classescomuns.jar conterá a classe Cliente que será utilizada pelo software Servidor e pelo software Cliente.

Então quando você passar a lista de objetos Cliente para os clientes de chat, estes clientes de chat conseguirão receber a lista de objetos Cliente, pois a classe Cliente está no classescomuns.jar, o qual está como lib no seu projeto de software Cliente.

valeu. Vou tentar então…