Ir ao conteúdo
  • Comunicados

    • Gabriel Torres

      Seja um moderador do Clube do Hardware!   12-02-2016

      Prezados membros do Clube do Hardware, Está aberto o processo de seleção de novos moderadores para diversos setores ou áreas do Clube do Hardware. Os requisitos são:   Pelo menos 500 posts e um ano de cadastro; Boa frequência de participação; Ser respeitoso, cordial e educado com os demais membros; Ter bom nível de português; Ter razoável conhecimento da área em que pretende atuar; Saber trabalhar em equipe (com os moderadores, coordenadores e administradores).   Os interessados deverão enviar uma mensagem privada para o usuário @Equipe Clube do Hardware com o título "Candidato a moderador". A mensagem deverá conter respostas às perguntas abaixo:   Qual o seu nome completo? Qual sua data de nascimento? Qual sua formação/profissão? Já atuou como moderador em algo outro fórum, se sim, qual? De forma sucinta, explique o porquê de querer ser moderador do fórum e conte-nos um pouco sobre você.   OBS: Não se trata de função remunerada. Todos que fazem parte do staff são voluntários.
    • DiF

      Poste seus códigos corretamente!   21-05-2016

      Prezados membros do Fórum do Clube do Hardware, O Fórum oferece um recurso chamado CODE, onde o ícone no painel do editor é  <>     O uso deste recurso é  imprescindível para uma melhor leitura, manter a organização, diferenciar de texto comum e principalmente evitar que os compiladores e IDEs acusem erro ao colar um código copiado daqui. Portanto convido-lhes para ler as instruções de como usar este recurso CODE neste tópico:  
Carlos Eduardo Rj

Trabalho - Login com servidor/cliente multi tarefas

Recommended Posts

Boa noite, vim aqui como último recurso depois de muito procurar.

Tenho um trabalho pra hoje, as 19h, onde preciso fazer uma interface que faça login consultando um banco de dados através de um servidor (e o servidor tem que ser multithread). Tenho muita dificuldade nisso, montei o banco, fiz a interface e o sistema de login com banco sql, que funciona normal (sem relação cliente/servidor). Com o servidor, depois de muito pesquisar, apenas consigo me conectar nele, e o servidor é multithread já. Mas não sei como faço para a partir do cliente, mandar as informações pro servidor, pra ele retornar se o login foi feito ou não, e como o servidor também se comunica com ele.

 

Não sei se estava no caminho certo, ou no caminho errado, mas na conexão com o servidor, o meu soquete era feito em outra classe, mas não consigo utilizá-lo em outra classe, onde está o meu login. E não sei como deixá-lo público, ou liberar a permissão pra isso.

 

Lembrando que estou contra o tempo, estou virando a noite pesquisando sem sucesso, se tiver alguém que domine isso e possa me ajudar, ficarei muito grato.

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • Autor do tópico
  •  

    Eu dei olhada no seu tópico, confesso que fiquei perdido. Estou precisando saber mais da parte do cliente, pois nele não consigo usar o socket da forma certa. Como você fez para enviar algo do cliente para o servidor? Eu fico travado com a conexão estabelecida, e quando saio dela para o formulário, o socket fica inacessável, não sei como poderia fazer isso. E não acho como faria pra passar o conteúdo dos objetos para o servidor, os tutoriais de chat são todos sem interface, usando scanner.

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    Olá.

     

    Eu não sei como o seu servidor foi implementado, mas vou dar como exemplo a forma que desenvolvi um programa desse há uns anos atrás (no momento não estou com o código aqui, mas se encontrar, mando o link compartilhando)

     

    1) No servidor (Multithread) eu tenho uma thread principal, que fica apenas ouvindo requisições de conexão (apenas login e autorização).

     

    2) Ao se conectar o servidor responde ao cliente o endereço de duas portas, e consequentemente cria duas threads ouvindo exatamente essas portas. Essas portas servirão de para a comunicação entre o servidor - cliente. (uma para envio, outra para resposta, evitando assim problemas de colisão de dados)

     

    3) Após isso essa primeira conexão é encerrada, e essa thread principal volta a ficar ouvindo requisições de conexão.

     

    ===

     

    4) No cliente, eu tenho uma classe de conexção no padrão singleton (para segurar o estado da conexão).

     

    5) Crio uma fila para recebimento das mensagens (Eu usei um List<String>, mas pode usar qualquer outra collection). Essa fila deverá ter um controle de leitura, garantindo que a mensagem será excluída da fila quando lida e que dois processos não poderão ter acesso simultâneo no mesmo objeto.

     

    6) Crio um método para envio de mensagens e outro para recebimento. O método de recebimento deverá ser uma Thread que ficará apenas ouvindo as mensagens do servidor e incluindo-as na fila de mensagens.

     



    BufferedReader inputMsg = new BufferedReader(new InputStreamReader(socketReceive.getInputStream()));
    String msg = inputMsg.readLine();
    msg.replace('\n', '\0');
    this.msgs.add(msg);


     

    7) Envio de mensagens é um método simples.

     




    PrintStream outputMsg = new PrintStream(socketSend.getOutputStream());
    outputMsg.println(msg);


     


    A partir daí, todo o resto vai de como você deseja implementar o protocolo de comunicação. Eu utilizei JSON com uma lista de comando próprios, e, por ser JSON, eu sempre recebia um objeto do outro lado para trabalhar ...

    Editado por psykotico

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  •  

    Olá.
     
    Eu não sei como o seu servidor foi implementado, mas vou dar como exemplo a forma que desenvolvi um programa desse há uns anos atrás (no momento não estou com o código aqui, mas se encontrar, mando o link compartilhando)
     
    1) No servidor (Multithread) eu tenho uma thread principal, que fica apenas ouvindo requisições de conexão (apenas login e autorização).
     
    2) Ao se conectar o servidor responde ao cliente o endereço de duas portas, e consequentemente cria duas threads ouvindo exatamente essas portas. Essas portas servirão de para a comunicação entre o servidor - cliente. (uma para envio, outra para resposta, evitando assim problemas de colisão de dados)
     
    3) Após isso essa primeira conexão é encerrada, e essa thread principal volta a ficar ouvindo requisições de conexão.
     
    ===
     
    4) No cliente, eu tenho uma classe de conexção no padrão singleton (para segurar o estado da conexão).
     
    5) Crio uma fila para recebimento das mensagens (Eu usei um List<String>, mas pode usar qualquer outra collection). Essa fila deverá ter um controle de leitura, garantindo que a mensagem será excluída da fila quando lida e que dois processos não poderão ter acesso simultâneo no mesmo objeto.
     
    6) Crio um método para envio de mensagens e outro para recebimento. O método de recebimento deverá ser uma Thread que ficará apenas ouvindo as mensagens do servidor e incluindo-as na fila de mensagens.
     
    BufferedReader inputMsg = new BufferedReader(new InputStreamReader(socketReceive.getInputStream()));String msg = inputMsg.readLine();msg.replace('\n', '\0');this.msgs.add(msg);
     
    7) Envio de mensagens é um método simples.
     
    PrintStream outputMsg = new PrintStream(socketSend.getOutputStream());outputMsg.println(msg);
     
    A partir daí, todo o resto vai de como você deseja implementar o protocolo de comunicação. Eu utilizei JSON com uma lista de comando próprios, e, por ser JSON, eu sempre recebia um objeto do outro lado para trabalhar ...

     

     

    Dei uma analisada, essa forma é utilizada pra mandar pro servidor usando o scanner, não? Queria utilizar interface, pra mandar o conteúdo de uma caixa de texto. E quanto a esse JSON, é algo fácil de utilizar? Não conheço isso, sou novato em Java. A ideia é fazer algo simples apenas para fins de trabalho mesmo, conectar, fazer a comunicação e receber os dados. Quer que eu deixe um link com o meu cliente e servidor?

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Eu dei olhada no seu tópico, confesso que fiquei perdido. Estou precisando saber mais da parte do cliente, pois nele não consigo usar o socket da forma certa. Como você fez para enviar algo do cliente para o servidor? Eu fico travado com a conexão estabelecida, e quando saio dela para o formulário, o socket fica inacessável, não sei como poderia fazer isso. E não acho como faria pra passar o conteúdo dos objetos para o servidor, os tutoriais de chat são todos sem interface, usando scanner.

     

     

    Assim eu conectei ao servidor:

        public void conecta() {        try {            conexao = new Socket("127.0.0.1", 2000);            entrada = new BufferedReader(new InputStreamReader(conexao.getInputStream()));            saida = new PrintStream(conexao.getOutputStream());            output = new ObjectOutputStream(conexao.getOutputStream());        } catch (IOException e) {            System.out.println(e);        }    }

    Para passar o conteúdo dos objetos para o servidor

    try {            conecta();            String valor1 = nomeDoCampo1.getText();            String valor2 = nomeDoCampo2.getText();            saida.println(valor1 + "@" + valor2 );        } catch (Exception e) {            System.out.println(e);        }

    e para o servidor ler e usar os valores passado:

    linha = entrada.readLine();split = linha.split("@");

    split é um array e cada elemento dele tem o conteudo de um campo da interface.

     

     

    Para retornar uma tabela de um resultset:

    Veja que precisa de uma classe dessa tebela

    query = "SELECT * from clientes where nome like '%" + split[1] + "%'";                        ResultSet rs = stmt.executeQuery(query);Vector<Cliente> c = new Vector<Cliente>();rs.beforeFirst();while (rs.next()) {    c.add(new Cliente(rs.getString("nomeDaColuna1"), rs.getString("nomeDaColuna2"), rs.getInt("nomeDaColuna3")));   } output.writeObject(c);rs.close();stmt.close();output.close();

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  •  

    Assim eu conectei ao servidor:

        public void conecta() {        try {            conexao = new Socket("127.0.0.1", 2000);            entrada = new BufferedReader(new InputStreamReader(conexao.getInputStream()));            saida = new PrintStream(conexao.getOutputStream());            output = new ObjectOutputStream(conexao.getOutputStream());        } catch (IOException e) {            System.out.println(e);        }    }

    Para passar o conteúdo dos objetos para o servidor

    try {            conecta();            String valor1 = nomeDoCampo1.getText();            String valor2 = nomeDoCampo2.getText();            saida.println(valor1 + "@" + valor2 );        } catch (Exception e) {            System.out.println(e);        }

    e para o servidor ler e usar os valores passado:

    linha = entrada.readLine();split = linha.split("@");

    split é um array e cada elemento dele tem o conteudo de um campo da interface.

     

     

    Para retornar uma tabela de um resultset:

    Veja que precisa de uma classe dessa tebela

    query = "SELECT * from clientes where nome like '%" + split[1] + "%'";                        ResultSet rs = stmt.executeQuery(query);Vector<Cliente> c = new Vector<Cliente>();rs.beforeFirst();while (rs.next()) {    c.add(new Cliente(rs.getString("nomeDaColuna1"), rs.getString("nomeDaColuna2"), rs.getInt("nomeDaColuna3")));   } output.writeObject(c);rs.close();stmt.close();output.close();

    Vou dar uma testada com isso ae. Eu colocaria a conexão para ser realizada ao abrir o formulário? Não sei como ordeno, se ao abrir a aplicação eu já conecto ao servidor (mantendo uma conexão o tempo todo para futuras comunicações), ou se conecto ao clicar no botão para validar, e fecho a conexão, e a realizo novamente a cada requisição.

    Desde já agradeço muito mesmo a ajuda que estou recebendo, já estou com uma direção pro que devo fazer, coisa que perdi há tempo.

     

    @Edit

     

    Tentei fazer aqui da seguinte forma:

    Uma classe chamada login.java (com a interface com os textos e botões), e uma classe chamada SocketTCPClient (onde deve ficar os comandos, validações e tudo mais. Deve ser feito em 3 camadas, e acho que é assim, ou estou fazendo errado..)

     

    No login tem os campos de texto t1 (guarda o login) e t2 (guarda a senha), e um botão que chama o método logar (da classe SocketTCPClient). E na classe SocketTCPClient, há o seguinte:

        public static void conecta() {        try {            Socket conexao2 = new Socket("192.168.56.1",12345);            System.out.println("O cliente se conectou ao servidor!");            BufferedReader entrada = new BufferedReader(new InputStreamReader(conexao2.getInputStream()));            PrintStream saida = new PrintStream(conexao2.getOutputStream());            ObjectOutputStream output = new ObjectOutputStream(conexao2.getOutputStream());        } catch (IOException e) {            System.out.println(e);        }    }        public static void logar(String login, String senha){        try {            conecta();            saida.println(login + "@" + senha);        } catch (Exception e) {            System.out.println(e);        }    }

    Porém em "saida.println(login + "@" + senha);", "saida" está dando erro "cannot find simbol", e não consigo colocar funcionando.

    Editado por Carlos Eduardo Rj

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

     

    Eu colocaria a conexão para ser realizada ao abrir o formulário?  conecto ao clicar no botão para validar, e fecho a conexão, e a realizo novamente a cada requisição.

     

    Foi assim que fiz o meu, a cada ação (clique de um botão para CRUD básico) chama o método conecta(), logo depois fecha conexão.

     

    também, não sei se é a melhor maneira assim como fiz, ou deixar a conexão sempre aberta. Mas funciona legal.

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Olá novamente.

     

    Respondendo a sua pergunta lá em cima:

     

     

     

    Dei uma analisada, essa forma é utilizada pra mandar pro servidor usando o scanner, não?

     

    Na verdade não. Essa forma serve para qualquer tipo de entrada de dados. Ele apenas está assumindo que você já resgatou o valor do TextField e validou num objeto String.

     

     

     

    E quanto a esse JSON, é algo fácil de utilizar? Não conheço isso, sou novato em Java. 

     

    JSON é um container de informação, assim como o XML, porém com um formato mais "compacto" e regras um pouco mais simples. como por exemplo

    {	"username" : "usuario",	"password" : "senha"}

    Se você já tiver um objeto com os atributos "username" e "password", existem bibliotecas (como a Jackson ou GSON) que "parseiam" essa string JSON acima e retornam o objeto que você deseja já instanciado e pronto para usar ;) ...

     

    ...

     

     

    Tentei fazer aqui da seguinte forma:

    Uma classe chamada login.java (com a interface com os textos e botões), e uma classe chamada SocketTCPClient (onde deve ficar os comandos, validações e tudo mais. Deve ser feito em 3 camadas, e acho que é assim, ou estou fazendo errado..)

     

    No login tem os campos de texto t1 (guarda o login) e t2 (guarda a senha), e um botão que chama o método logar (da classe SocketTCPClient). E na classe SocketTCPClient, há o seguinte:

        public static void conecta() {        try {            Socket conexao2 = new Socket("192.168.56.1",12345);            System.out.println("O cliente se conectou ao servidor!");            BufferedReader entrada = new BufferedReader(new InputStreamReader(conexao2.getInputStream()));            PrintStream saida = new PrintStream(conexao2.getOutputStream());            ObjectOutputStream output = new ObjectOutputStream(conexao2.getOutputStream());        } catch (IOException e) {            System.out.println(e);        }    }        public static void logar(String login, String senha){        try {            conecta();            saida.println(login + "@" + senha);        } catch (Exception e) {            System.out.println(e);        }    }

    Porém em "saida.println(login + "@" + senha);", "saida" está dando erro "cannot find simbol", e não consigo colocar funcionando.

     

    Nesse código, você está esperando receber uma mensagem nessa linha:

    BufferedReader entrada = new BufferedReader(new InputStreamReader(conexao2.getInputStream())); 

    Se o servidor e o cliente simultaneamente enviarem dados, nenhum dos dois conseguirá receber a informação.

     

    Então, depende muito de como é a tratativa no servidor. Se o servidor manda msg logo após a conexão, não está errado. Mas se o servidor não estiver enviando nada, você receberá exatamente esse erro que você comentou.

     

    Para enviar uma msg para o servidor (e vice-versa) você precisa usar o seguinte comando:

    PrintStream saida = new PrintStream(conexao2.getOutputStream());saida.println(msg);

    Onde msg é um string contendo a mensagem.

     

    Por isso comentei que o melhor é você ter 2 conexões: uma para envio de msgs e outra para recebimento de msgs. E, para isso, é bom utilizar Threads, para poder fazer os dois processos "simultaneamente" ...

     

    Sei que você está começando agora, e você está indo muito bem ... eu sempre penso assim: Primeiro fazer funcionar, depois fazer ficar melhor, por ultimo deixar o código o melhor possível para manutenção ;) ...

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Crie uma conta ou entre para comentar

    Você precisar ser um membro para fazer um comentário






    Sobre o Clube do Hardware

    No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

    Direitos autorais

    Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

    ×