Duvidas (Muitas): Socket

Boa tarde, primeiramente vou contar uma breve historia e dizer o que quero fazer.

Fui contratado em uma empresa de segurança eletronica como estagiario, tenho um conheçimentro basico de Java Basico (fiz um curso de java da softblue) surgiu que o meu patrão quer trabalhar com leitores RFid, e sobrou pra mim fazer o software que vai receber as informações das TAGs e manipulala.

O que eu preciso, fazer um conecção TCP com a antena, para enviar o comando RQL e receber as informações das TAGs que ela está lendo.

Fiquei 3 dias no forum e no google lendo sobre sockets mais infelizmente não achei o que eu quero, achei no minimo uns 4 chats TCP, consegui fazer 2 deles funcionarem, mais, mesmo me baseando neles não consegui criar o que preciso.

Tenho uma base do que seja, quero algo bem basico de começo.

Não quero nada visual, pode ser puro console, alguem pode me dizer onde encontro exemplos do que preciso?

Caso alguem possa me dar um luz no fim do tunel, queria exemplo de um aplicativo em java que envia 1 string e recebe outras atravez de socket.

PS: Ja pesquisei sobre a API rfid do java, mais para o que eu quero creio que apenas socket ja basta, infelizmente, como so fiz curso basico, não entendo muito disso.

Entendo Sockets
http://www.sumersoft.com/publicacoes/SocketsEmJAVA.pdf
http://javafree.uol.com.br/artigo/2879/Programando-com-sockets-em-java-parte-01.html

Exemplos:

http://www.exampledepot.com/taxonomy/term/196

Abraço

Obrigado pelos links saulods.

Lendo umas coisas sobre sockets eu fiz o seguinte codigo

[code]import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Aplicação {

public ServerSocket servidor;
public Socket abc;
public DataInputStream vem;
public DataOutputStream vai;

public Aplicação(){

try{
	servidor = new ServerSocket(8080);
	abc = new Socket("10.0.0.101", 8080);
	vem = new DataInputStream(abc.getInputStream());
	vai = new DataOutputStream(abc.getOutputStream());
}
catch(IOException msg){
	System.out.println(msg.getMessage());
}

}

public static void main(String[] args) throws IOException {

	System.out.println("Conectando o Reader e enviando comando...");
	Aplicação apli = new Aplicação();
	apli.vai.writeUTF("SELECT read_count, protocol_id, antenna_id, id FROM tag_id WHERE protocol_id='GEN2' set time_out=1000");
	System.out.println("Comando enviado, aguardando resposta");
	String resposta = apli.vem.readUTF();
	System.out.println(resposta);

}
}
[/code]

Porem, como eu ja esperava (infelizmente) não funcionou.

Mas ja foi um grande avanço

Da primeira vez que eu dei Run no codigo achei que iria funcionar mais ele mostrou no console

Conectando o Reader e enviando comando... Comando enviado, aguardando resposta Exception in thread "main" java.net.SocketException: Software caused connection abort: recv failed at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(Unknown Source) at java.io.DataInputStream.readFully(Unknown Source) at java.io.DataInputStream.readUTF(Unknown Source) at java.io.DataInputStream.readUTF(Unknown Source) at Aplicação.main(Aplicação.java:32)

Apartir da seguinda vez que eu dei Run passou a mostrar o seguinte:

Exception in thread "main" java.lang.NullPointerException at Aplicação.main(Aplicação.java:30) Conectando o Reader e enviando comando... Unrecognized Windows Sockets error: 0: JVM_Bind

Alguma luz? :smiley:

Cheguei perto ou o que eu fiz não tem nada haver com o certo?

Passou longe. Antes de mais nada, você precisa escrever dois programas, um cliente e outro servidor. O seu programa servidor deve ficar em loop, aguardando uma conexão. Quando uma conexão é aceita você faz alguma tarefa com os dados e retorna ao estado de aguardo. Já o seu programa cliente deve requisitar uma conexão no endereço e na porta do servidor e enviar os seus dados. Mas a dica quente é essa: escreva programas separados.

Poderia me passar algum exemplo?

Você vai escrever um socket para se conectar onde? Pq a antena não é um servidor.

Se a sua solução de RFid já tiver um servidor, então você precisa ir até o site do fabricante e baixar a documentação do protocolo desse fabricante, e obedecer esse protocolo.

O que o erro de socket que você apontou indica é que a conexão foi abortada. Então, você provavelmente se conectou em algum lugar e tentou mandar um SQL de qualquer jeito, sem obedecer nenhum tipo de protocolo. O servidor, que aguardava algum tipo de handshake, interpretou isso como uma conexão inválida e fechou o socket.

Não posso entrar em detalhes de como seria esse protocolo, pois isso varia de fabricante para fabricante. Mas se você nem tem noção do que seja um protocolo, leia esse post: http://www.guj.com.br/posts/list/136538.java#735860

[quote=ViniGodoy]Você vai escrever um socket para se conectar onde? Pq a antena não é um servidor.

Se a sua solução de RFid já tiver um servidor, então você precisa ir até o site do fabricante e baixar a documentação do protocolo desse fabricante, e obedecer esse protocolo.

O que o erro de socket que você apontou indica é que a conexão foi abortada. Então, você provavelmente se conectou em algum lugar e tentou mandar um SQL de qualquer jeito, sem obedecer nenhum tipo de protocolo. O servidor, que aguardava algum tipo de handshake, interpretou isso como uma conexão inválida e fechou o socket.

Não posso entrar em detalhes de como seria esse protocolo, pois isso varia de fabricante para fabricante. Mas se você nem tem noção do que seja um protocolo, leia esse post: http://www.guj.com.br/posts/list/136538.java#735860
[/quote]

Existe um servidor na propria antena, acabei de ligar no fabricante da antena.

Ja estou com a documentação em mãos.

Segundo o fabricante, a antena possui um microprocessador, então basta enviar os dados com protocoloc RQL (foi o que eu enviei usando writeUTF que ela ira enviar a resposta, mencionei que estava fazendo em java o programa e ele me falou que em VB basta usar winsocket e enviar o comando

Lendo a documentação obtive o seguinte

Que o leitor não entra em contato com o software cliente, o software cliente precisa iniciar um coneção (imagino que seja um tunel TCP).

Agora ja me surgiu a duvida, devo usar os 2 programas que o rmendes08 mencionou? Um servidor e um programa que ira processar os dados, ou não preciso mais do servidor?

… ta complicadinho isso e a pressão ta almentando :x

Não precisa, porque você já tem o servidor. Só precisa do cliente.

De qualquer forma, é bom usar um programa como o wireshark para ver o que está indo e vindo na rede. Aí vc pelo menos observa se sua mensagem está indo da forma que você espera.

Se você tiver o programa VB, pode usar esse software para comparar o que o VB envia com o que você envia.

[quote=ViniGodoy]Não precisa, porque você já tem o servidor. Só precisa do cliente.

De qualquer forma, é bom usar um programa como o wireshark para ver o que está indo e vindo na rede. Aí vc pelo menos observa se sua mensagem está indo da forma que você espera.

Se você tiver o programa VB, pode usar esse software para comparar o que o VB envia com o que você envia.

[/quote]

Origado, ja estou baixando o wireshark, mais uma perguntinha, sobre o software cliente, é mais o menos aquilo que está na terçeira resposta desse topico, ou aquilo não tem nada haver com o que preciso?

Nunca usei esse wireshark, porem, pelo que vi, acho que a conecção desse meu programinha que postei na 3ª resposta do topico está funcionando, segue abaixo a SS

http://yfrog.com/b6wiresharkj

Isso acima aconteçeu quando eu apertei Run no eclipse, isso quer dizer que pelo menos o socket está funcionando? Pois ele enviou informações para a Antena, e a Antena respondeu correto?

PS: Eu sou o ip com final 102 e a antena é a com final 101

Baixei a documentação do RQL aqui e, aparentemente, é aquilo sim. Mas cuidado que as vezes um encoding ou uma quebra de linha errada pode fazer o servidor reclamar.

Baixei a documentação do RQL aqui e, aparentemente, é aquilo sim. Mas cuidado que as vezes um encoding ou uma quebra de linha errada pode fazer o servidor reclamar.[/quote]

ViniGodoy, muito obrigado por tudo, agora vai um texto…

Usei o seguinte codigo:

[code]import java.net.Socket;
import java.io.*;

public class Teste {
public static void main(String[] args) throws IOException {

Socket clientSocket = new Socket("10.0.0.101", 8080);
 DataInputStream inbound = new DataInputStream ( clientSocket.getInputStream( ) );
 DataOutputStream outbound = new DataOutputStream ( clientSocket.getOutputStream( ) );
 outbound.writeUTF("SELECT id FROM tag_id WHERE protocol_id='GEN2' AND antenna_id=1;");
 System.out.println("Foi");
 inbound.close () ;
 outbound.close () ;
 
 clientSocket.close() ;

}
}[/code]

E para minha felicidade ele “funcionou”
Ele enviar o comando RQL: SELECT id FROM tag_id WHERE protocol_id=‘GEN2’ AND antenna_id=1; para a antena e a antena responde
http://img694.imageshack.us/img694/4781/13229861.jpg
E era isso mesmo que eu queria.

Porem se eu substituio para o comando RQL que altera o id da TAG: UPDATE tag_id SET id=0x0001 WHERE protocol_id=‘GEN2’ AND antenna_id=1;
A antena me da um erro, dei uma olhada no Wireshark e descobri por que da o erro
Meu “programinha” em vem de enviar

UPDATE tag_id SET id=0x WHERE protocol_id='GEN2' AND antenna_id=1;

Ele envia

RUPDATE tag_id SET id=0x WHERE protocol_id='GEN2' AND antenna_id=1;

E a antena me da um erro dizendo que o comando RUPDATE não é valido

Queria saber daonde vem esse ‘R’, por que ja olhei 10x para o codigo e não tem nenhuma string R nem nada do tipo lá.

Resumindo, o socket está quase fazendo o que eu queria, só quero mesmo descobrir daonde vem esse R.

Agora vem mais uma duvida

Se vocês verem na schenshot, a antena respondeu meu comando SELECT corretamente, queria saber como posso capturar essa resposta e trazela para meu programinha em Java.

Obrigado novamente a todos que estão me ajudando, e desculpa por tudo, é que começei no mundo do Java a umas 3 semanas, começei pra valer segunda feira, então tenham pasciencia comigo. :twisted:

Teste fazendo:

outBound.write("SELECT id FROM tag_id WHERE protocol_id='GEN2' AND antenna_id=1;".getBytes());

Só para confirmar que não é um problema do padrão UTF.

Pelo menos com wireshark não tem erro, vc sabe exatamente o que está saindo. :slight_smile:

[quote=ViniGodoy]Teste fazendo:

outBound.write("SELECT id FROM tag_id WHERE protocol_id='GEN2' AND antenna_id=1;".getBytes());

Só para confirmar que não é um problema do padrão UTF.

Pelo menos com wireshark não tem erro, vc sabe exatamente o que está saindo. :)[/quote]

Quando eu tiver no trabalho eu testo, a antena fica lá, e ja cheguei em casa :stuck_out_tongue:

Exatamente, gostei muito desse programa.

:arrow: Perguntinha, tem algum link sobre como eu posso receber as informações que a antena envia?

Eu vi que ela envia atravez do Wireshark agora só falta achar um geito de leva-la para o programa em java e imprimir ela no console…

Depois disso começo a fazer o projeto pro programa de RFID :shock:

Ainda to na etapa -0.1% depois que fazer o que falei acima vo pra 0% do programa concluido hahaha :smiley:

Você tem que deixar uma thread monitorando aquele inbound ali. Ele recebe tudo que “volta” pelo socket.

A thread então recebe os dados e joga-os para um JTextArea.

Certo, e como posso fazer um thread ficar monitorando a porta 8080 TCP?

Eu fiz umas pesquisas sobre threads, ja entendi como ele funciona, mais não encontrei nada relacionando thread com monitoramento de porta e pouca coisa sobre JTextArea, poderia me passar alguma dica de onde/como procura esse conteudo? Ou me passar alguns links?

– edit –

Depois de umas leituras entendi um pouco mais sobre esse assuntos, por favor me corrigam se eu estiver errado

O que eu vou ter que fazer é criar um thread e nele colocar um while para ficar dando outbound.reader(blabla.getByter()); e como posso fazer pra essa informação que ele pegar seja jogada na Jtextarea?

Vou ter que criar uma conecção como no outro codigo tambem certo usando o Socket ou ServSocket?

Obrigado pela atenção

Você conectou seu socket, e ele é birecional. Para uma thread monitorar esse socket, basta que ela fique fazendo read no inbound. E, sempre que chegar algum dado, você deve trata-lo. O método read bloqueia caso não hajam dados para serem lidos.

Os programas de chat que você achou devem fazer algo assim.

Eu tentei fazer e deu no codigo abaixo. Porem, como ja era de se esperar, ele não compila, e nem deveria, eu estou com dificuldade na linha 14

[code]import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;

public class SocketRecpeção extends Thread{

public static void main(String[] args){
	
		try {
		System.out.println("Iniciando servidor... aguarde...");
		ServerSocket servidor = new ServerSocket(7171);
		System.out.println("Servidor iniciado com sucesso.");
		DataInputStream entrada = new DataInputStream(entrada.readUTF());
                    //Ta feia a coisa na linha de cima, não sei o que fazer nela
		while(true){
			System.out.println(entrada);
		}
		} catch (IOException erro) {
		System.out.println(erro);
		System.exit(0);
		}	

}
}[/code]

Poderia me dar uma ajudinha?

Eu olhei os chats que eu baixei, dei uma pesquisada no google, mais to a mais o menos 1 hora sem sair do lugar :?

Putz… vc sabe trabalhar com threads? O código acima indica fortemente que não.

Eu fiz uma implementação de socket realmente trivial aqui.
http://www.guj.com.br/posts/list/15/74218.java#506163

A parte de recepção dela deve ser muito parecida com a que você vai usar.

Como é um código muito comentado e feito exclusivamente para console, talvez fique mais fácil para você entender.

Boa tarde amigos do GUJ forum que está salvando meu estagio :twisted:

Meu programa está quase ponto, porem, ainda não consegui escutar a antena, mas, consegui fazer com que meu programa se comunique outro computador, acho que o erro está na forma com que eu falo para meu programa receber a mensagem:

Recebo no servidor da seguinte forma

entrada = new BufferedReader(new InputStreamReader(socket.getInputStream())); System.out.println(entrada.readLine());

Como ja era de se esperar, se eu mando este socket monitorar a porta 8080 e envio uma informação da antena para o computador ele não “pega” essas informações.
Ja se eu enviar de outro computador atravez da porta 8080 usando:

PrintStream ps = new PrintStream(s.getOutputStream()); Ele imprimi na tela.

Poderiam me dar uma ajuda de que usar para ele pegar tudo que vem pela 8080 e não apenas o que vem como getOutputStream?

Obrigado.
Allan

Não entendi. No inputStream do socket que conecta com a antena não vem nada?