Comunicação Socket Duas Vias com somente uma porta
12/01/2011
0
Boa tarde, amigos.
Estou com um problema para resolver um bocado complicado.
Estou implementando a integração com um aparelho via Socket TCP/IP. O protocolo deste aparelho funciona de uma maneira em que assim que o aparelho for conectado, ele manda uma string de autorização para o computador servidor, que deve estar escutando o mesmo. Ao validar esta string, é necessário retornar um ACK para o aparelho dizendo que a autenticação do mesmo foi aceita, e a partir daí toda a comunicação com o aparelho é feita na via reversa, ou seja, o computador servidor mandando comandos para o aparelho, e este aparelho respondendo ACK ou NACK conforme for o caso.
Normalmente, isso é feito utilizando duas portas, mas o aparelho só permite uma configuração de porta de comunicação, e aí após retornar o ACK para a autenticação do aparelho, duas coisas acontecem:
1. Se desconectar o socket e abrir um socket novo, cliente do aparelho, o aparelho recusa a conexão exigindo novamente uma autenticação;2. Se não desconectar o socket e tentar utilizar a mesma conexão para enviar dados, não há resposta alguma do aparelho, com a conexão sendo forçadamente cancelada.
O código que estou utilizando é o seguinte (nomes das classes alteradas para não revelar o aparelho).
Estou com um problema para resolver um bocado complicado.
Estou implementando a integração com um aparelho via Socket TCP/IP. O protocolo deste aparelho funciona de uma maneira em que assim que o aparelho for conectado, ele manda uma string de autorização para o computador servidor, que deve estar escutando o mesmo. Ao validar esta string, é necessário retornar um ACK para o aparelho dizendo que a autenticação do mesmo foi aceita, e a partir daí toda a comunicação com o aparelho é feita na via reversa, ou seja, o computador servidor mandando comandos para o aparelho, e este aparelho respondendo ACK ou NACK conforme for o caso.
Normalmente, isso é feito utilizando duas portas, mas o aparelho só permite uma configuração de porta de comunicação, e aí após retornar o ACK para a autenticação do aparelho, duas coisas acontecem:
1. Se desconectar o socket e abrir um socket novo, cliente do aparelho, o aparelho recusa a conexão exigindo novamente uma autenticação;2. Se não desconectar o socket e tentar utilizar a mesma conexão para enviar dados, não há resposta alguma do aparelho, com a conexão sendo forçadamente cancelada.
O código que estou utilizando é o seguinte (nomes das classes alteradas para não revelar o aparelho).
public ServidorAparelho(int Porta, String IDAparelho) { // do Manual de Integradores do DigiREP /*Quando DigiREP se conecta ao servidor, ele enviará uma mensagem de com o número da sua MRP, deve-se calcular o CRC e se estiver correto envia-se um ACK, caso contrário derruba- se a conexão com este DigiREP. Sugerimos que após a autenticação seja enviado o cadastro da empresa, pois o DigiREP não irá cadastrar nenhuma pessoa se não possuir o cadastro da empresa e em seguida envia- se o tipo de validação biométrica, pois o tipo de validação padrão é Cartão ou Biometria. */ this.port = Porta; this.deviceID = IDAparelho; TcpListener listener = new TcpListener(IPAddress.Any, this.port); listener.Start(); using (TcpClient client = listener.AcceptTcpClient()) { NetworkStream stream = client.GetStream(); byte[] message = new byte[1024]; int bytesRead; String receivedTextBuffer = ""; bytesRead = stream.Read(message, 0, 1024); if (bytesRead > 0) { receivedTextBuffer = ByteUtils.getStringFromBytes(message); } if (!(String.IsNullOrEmpty(receivedTextBuffer))) { receivedTextBuffer = receivedTextBuffer.Replace("\0", ""); if (this.ValidateAuthString(receivedTextBuffer)) { ReturnAckTo(stream); //listener.Stop(); //stream.Close(); //client.Close(); //TcpClient sender = new TcpClient(); //sender.Connect("10.0.6.100", 9000); //stream = sender.GetStream(); Mensagem deviceMsg = new Mensagem(); deviceMsg = "teste"; byte[] msgToSend = deviceMsg.buildMessage(); stream.Write(msgToSend, 0, msgToSend.Length); if (stream.CanRead) { // receber a resposta para saber se a mensagem foi aceita pelo aparelho. bytesRead = stream.Read(message, 0, 1024); if (bytesRead > 0) { receivedTextBuffer = ByteUtils.getStringFromBytes(message); } } } else { ReturnNackTo(stream); listener.Stop(); } } else { ReturnNackTo(stream); listener.Stop(); } stream.Close(); } }
Pablo Oliveira
Curtir tópico
+ 0
Responder
Posts
Clique aqui para fazer login e interagir na Comunidade :)