Problema com sockets para enviar mensagem do servidor para todos os clientes!

6 respostas
andersonrc

Olá galera,

tenho que implementar um projeto de pseudo twitter, e um dos requisitos é do servidor enviar mensagem para todos os clientes.

O problema que estou tendo é que o servidor só envia mensagem para o primeiro cliente que for executado. Quando executo o 2º cliente, em outra console ou outro host ele não recebe as mensagens, apenas o 1º que conectou que recebe.

Então abaixo seguem os códigos até o momento.

Alguém sabe aonde tá o problema?

E outra coisa, já tentei colocar o ServerSocket e o acept pra aceitar conexões no main, tirando do método enviarMensagemParaTodosSeguidores(). Só que quando executo dá NullPointerException. Aí por isso que por enquanto tá fora do main, pq desse jeito tá rodando.

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

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 *
 * @author andersonribeiro
 */
public class Servidor {

    private static int porta = 5000;
    private static String nomeServidor = "SERVIDOR SOCKET";

    public String getNomeServidor() {
        return nomeServidor;
    }

    public void setNomeServidor(String nomeServidor) {
        Servidor.nomeServidor = nomeServidor;
    }

    public static int getPorta() {
        return porta;
    }

    public static void setPorta(int porta) {
        Servidor.porta = porta;
    }

    //MÉTODO PARA O SERVIDOR ENVIAR MENSAGEM PARA TODOS OS SEGUIDORES
    public void enviarMensagemParaTodosSeguidores() {

        try {

            ServerSocket s = new ServerSocket(porta);

            Servidor servidor = new Servidor();

            System.out.println("Olá: " + servidor.getNomeServidor() + "\nConectado na porta: " + Servidor.getPorta());

            String str;

            Socket c = s.accept();

            while (true) {

                DataInputStream entrada = new DataInputStream(c.getInputStream());
                DataOutputStream saida = new DataOutputStream(c.getOutputStream());

                do {
                    System.out.print("Enviar mensagem aos seguidores > ");
                    byte[] line = new byte[100];
                    System.in.read(line);

                    System.out.print(servidor.getNomeServidor() + " twittou > ");
                    saida.write(line);
                    entrada.read(line);
                    str = new String(line);
                    System.out.println(str.trim());

                } while (!str.trim().equals("quit"));

                c.close();
                System.out.println("\nServidor desconectado!");
            }
        } catch (Exception e) {
            System.out.println(e);
        }

    }

    public static void main(String[] args) {

        new Servidor().enviarMensagemParaTodosSeguidores();

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

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;

/**
 *
 * @author andersonribeiro
 */
public class Cliente {

    private static int porta = 5000;
    private static String IP = "127.0.0.1";
    private static String nomeSeguidor;

    public static int getPorta() {
        return porta;
    }

    public static void setPorta(int porta) {
        Cliente.porta = porta;
    }

    public static String getIP() {
        return IP;
    }

    public static void setIP(String IP) {
        Cliente.IP = IP;
    }

    public static String getNomeSeguidor() {
        return nomeSeguidor;
    }

    public static void setNomeSeguidor(String nomeSeguidor) {
        Cliente.nomeSeguidor = nomeSeguidor;
    }

    //MÉTODO QUE RECEBE MENSAGEM DO SERVIDOR
    public void receberMensagemDoServidor() {

        try {
            
            Socket s = new Socket(IP, porta);
            System.out.println("Cliente conectado!");

            DataInputStream i1 = new DataInputStream(s.getInputStream());
            DataOutputStream o1 = new DataOutputStream(s.getOutputStream());

            String str;

            do {
                byte[] line = new byte[100];
                i1.read(line);
                o1.write(line);
                str = new String(line);

                System.out.print("Servidor twittou: ");
                System.out.println(str.trim());

            } while (!str.trim().equals("quit"));

            s.close();
            System.out.println("\nServidor desconectado!");
        } catch (Exception e) {
            System.out.println(e);
        }

    }

    public static void main(String[] args) {

       new Cliente().receberMensagemDoServidor();
    }
}

6 Respostas

Guilherme_Gomes

O seu método enviarMensagemParaTodosSeguidores() está errado.

Você deve abrir uma Thread pra ficar dando accept() de novos clientes. E outra Thread (ou a atual) pra ficar enviando as mensagens. Lembrando que deve manter referencia dos clientes!!!

andersonrc

Guilherme Gomes:
O seu método enviarMensagemParaTodosSeguidores() está errado.

Você deve abrir uma Thread pra ficar dando accept() de novos clientes. E outra Thread (ou a atual) pra ficar enviando as mensagens. Lembrando que deve manter referencia dos clientes!!!

Obrigado Guilherme, vou tentar com threads então.

andersonrc

Fiz algumas alterações na classe Servidor, e debuguei. Apesar de ter thread, sempre tá indo para o catch do método enviarMensagemParaTodosSeguidores() dando NullPointerException, ele entra no do while(), mas acaba indo para o catch

Alguém sabe como resolver isso?

Segue o código alterado

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

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 *
 * @author andersonribeiro
 */
public class Servidor extends Thread {

    private static int porta = 5000;
    private static String nomeServidor = "SERVIDOR SOCKET";
    private static Servidor servidor;
    private Socket socket;

    public Servidor(Socket socket) {

        this.socket = socket;
    }

    public String getNomeServidor() {
        return nomeServidor;
    }

    public void setNomeServidor(String nomeServidor) {
        Servidor.nomeServidor = nomeServidor;
    }

    public static int getPorta() {
        return porta;
    }

    public static void setPorta(int porta) {
        Servidor.porta = porta;
    }

    public static Servidor getServidor() {
        return servidor;
    }

    public static void setServidor(Servidor servidor) {
        Servidor.servidor = servidor;
    }

    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }

    //MÉTODO PARA O SERVIDOR ENVIAR MENSAGEM PARA TODOS OS SEGUIDORES
    public void enviarMensagemParaTodosSeguidores() {

        try {

            String str;

            while (true) {

                DataInputStream entrada = new DataInputStream(socket.getInputStream());
                DataOutputStream saida = new DataOutputStream(socket.getOutputStream());

                do {
                    System.out.print("Enviar mensagem aos seguidores > ");
                    byte[] line = new byte[100];
                    System.in.read(line);

                    System.out.print(servidor.getNomeServidor() + " twittou > ");
                    saida.write(line);
                    entrada.read(line);
                    str = new String(line);
                    System.out.println(str.trim());

                } while (!str.trim().equals("quit"));

                socket.close();
                //System.out.println("\nServidor desconectado!");

            }
        } catch (Exception e) {
            System.out.println(e + "->> Erro 1");
        }

    }

    @Override
    public void run() {

        while (true) {
            enviarMensagemParaTodosSeguidores();
        }
    }

    public static void main(String[] args) {
        try {
            ServerSocket socketServer = new ServerSocket(porta);

            //System.out.println("Olá: " + servidor.getNomeServidor()
            //        + "\nConectado na porta: " + Servidor.getPorta());

            while (true) {

                Socket socket = socketServer.accept();

                Servidor thread = new Servidor(socket);
                thread.start();

            }

        } catch (IOException ex) {
            System.out.println(ex + "->> Erro 2");
        }

    }
}
jose_castilho

Boa tarde,

É um requisito efetuar a implementação com Sockets? Já chegou a pesquisar Filas JMS?
A especificação JMS por si só já resolve grande parte de seus desafios sem a necessidade de implementar a conexão via sockets.

Segue um link sobre a HornetQ: http://hornetq.sourceforge.net/docs/hornetq-2.0.0.BETA5/quickstart-guide/en/html_single/index.html

Quaisquer dúvidas estou à disposição.

andersonrc

Guilherme Gomes:
O seu método enviarMensagemParaTodosSeguidores() está errado.

Você deve abrir uma Thread pra ficar dando accept() de novos clientes. E outra Thread (ou a atual) pra ficar enviando as mensagens. Lembrando que deve manter referencia dos clientes!!!

"Lembrando que deve manter referencia dos clientes!!! " Essa referência seria através de um List de Sockets para o servidor guardar a sessão de cada cliente que se conectar a ele?

andersonrc

jose_castilho:
Boa tarde,

É um requisito efetuar a implementação com Sockets? Já chegou a pesquisar Filas JMS?
A especificação JMS por si só já resolve grande parte de seus desafios sem a necessidade de implementar a conexão via sockets.

Segue um link sobre a HornetQ: http://hornetq.sourceforge.net/docs/hornetq-2.0.0.BETA5/quickstart-guide/en/html_single/index.html

Quaisquer dúvidas estou à disposição.

Obrigado pela dica jose, mas tem que ser com sockets sim.

Criado 9 de novembro de 2011
Ultima resposta 9 de nov. de 2011
Respostas 6
Participantes 3