Socket entre Servidor em Java e cliente em C

7 respostas
Arist_eles

Bom dia pessoal!

Estou com um problema sério, criei um servidor em Java, conexão TCP e tenho um cliente em C, no entanto as vezes o pacote que o cliente me envia (apenas String) eu não recebo.
O cliente está rodando em uma plataforma linux embarcado e o servidor em um PC no Windows XP SP2.
Criei um cliente em java para realizar alguns testes, e não deu nenhum problema literalmente, agora estou forçando os testes, enviado dados a cada 100ms, e no momento já foram 4050 dados e todos respondidos sem enhum problema.
(Cliente envia “ATIVO” e servidor responde “OKATIVO”).

Será que esse problema que estou tendo é alguma incompatibilidade entre linguagens ou plataformas?

Desde já agradeço a ajuda que for prestada. Muito obrigado!

7 Respostas

T

Não deveria haver problemas. Como é que você recebe a string em Java?

Arist_eles

Segue a forma como estou tratando o que recebo. Estou usando ServerSocketChannel e SocketChannel

while (true) { // While que recebe constantemente os dados
ByteBuffer newData = ByteBuffer.allocate(100); // ByteBuffer para novos dados
novoCliente.read(newData); //Aguarda até um novo dados chegar

if (newData == null) {
                    System.out.println(">>>>> Cliente desconectou!!! DADO RECEBIDO É IGUAL A null <<<<<"); // DEBUG << ----------------------------------
                    closeCliente();
                    this.stop(); // Finaliza a Thread
                } else {
                    //recebe dados e monta a string
                    int i = 0;
                    while (newData.getInt(i) != 0) {
                        char ASCII = (char) newData.get(i);
                        recept += ASCII;
                        i++;
                    } // Fim do While que monta a string recebida
         
                        ...

        }
T

O cliente C tem de mandar 4 bytes 0 para indicar que é o fim de uma string? (que protocolo horrível que você inventou).

Arist_eles

Não, na minha concepção após o último caracter vai ter 0 ou -1 então ele finaliza, teria uma sugestão melhor? Pois no momento essa é a forma mais funcional que encontrei.

Obrigado pela ajuda.

T

Eu sempre aconselho, se você for inventar seu próprio protocolo usando sockets TCP, a criá-lo orientado a mensagens.
No começo de cada mensagem, mande o tamanho (como um inteiro de 4 bytes, em “network byte order”) e depois os dados.
Então você, ao receber uma mensagem, lê o tamanho e depois espera ler o resto dos dados. Provavelmente os dados não virão todos de uma só vez, então você tem de ficar acumulando os dados até receber a mensagem completa.

Dê uma olhada num server bem estúpido (não usa NIO nem nada muito complicado) em:

http://www.guj.com.br/posts/list/133367.java#718805

Atenção - no meu exemplo, o cabeçalho só tem 2 bytes (readShort), não 4.

Arist_eles

Mudei a forma de recer os dados para:

novoCliente.read(newData);

byte recebido[] = newData.array();

String recept = new String (recebido);

Outra dúvida que tenho é a seguinte, qual seria a forma mais correta para saber quando o cliente desconectou de forma anormal, por exemplo, quando o cabo de rede for retirado.
Hoje eu tenho um timeout de 3 minutos, se caso eu não receber nada durante 3 minutos desconecto o cliente.

T

Arist?eles:
Mudei a forma de recer os dados para:

novoCliente.read(newData);

byte recebido[] = newData.array();

String recept = new String (recebido);

Não faça isso. Para mensagens pequenas e com intervalos de tempo grandes entre si, isso funciona. Entretanto, se a mensagem for grande, ela ficará fragmentada (isso porque o TCP/IP é assim; não há o que você possa fazer) e se as mensagens forem pequenas, mas sem intervalos de tempo muito grandes entre si, elas virão “grudadas”. Ainda peço encarecidamente para você ler meu código que postei.

Criado 24 de agosto de 2009
Ultima resposta 24 de ago. de 2009
Respostas 7
Participantes 2