Ir ao conteúdo
  • Cadastre-se

Trabalho - Login com servidor/cliente multi tarefas


Posts recomendados

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.

Link para o comentário
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.

Link para o comentário
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 ...

Link para o comentário
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 ...

 

 

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?

Link para o comentário
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();
Link para o comentário
Compartilhar em outros sites

 

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.

Link para o comentário
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.

Link para o comentário
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 ;) ...

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades 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

×
×
  • Criar novo...