Manter um socket aberto enviando mensagem  XML
Índice dos Fóruns » Java Avançado
Autor Mensagem
laudenpower
JavaEvangelist
[Avatar]

Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline

Olá pessoal, bem estou implementando um sistema clienteXservidor onde eu quero abrir um socket no cliente e mante-lo aberto durante todo o ciclo de vida do aplicativo cliente apenas mandando mensagens para o servidor. Acontece que eu até consigo manter ele aberto porém tudo que eu mando para o servidor só é enviado de fato mesmo quando eu fecho o socket no cliente, mas ai nesse caso eu perco a conexão. Já tentei mandar um '\n' no fim da mensagem mas nesse caso é a mesma coisa que se eu fechasse o socket, tipo o que eu quero mesmo é que ele fique aberto o tempo todo sendo que eu apenas chamaria um método para mandar a mensagem para o servidor.
Eu fiz uns testes com um servidor feito em delphi e nesse caso quando eu dava um in.write(algum byte) seguido de um in.flush(); o servidor mostrava na tela normalmente a mensagem vinda do cliente, mas quando eu fiz isso em um servidor feito em java a coisa não deu certo.
Enfim era essa a minha pergunta, é possível manter esse socket aberto enviando mensagens?

Desde já grato pela atenção.

Enquanto cultivares teu saber, nada tens a temer!

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999
ViniGodoy
Moderador
[Avatar]

Membro desde: 11/12/2006 08:22:01
Mensagens: 20576
Localização: Curitiba/PR
Offline

Sim, é possível.

Como você está fazendo a leitura do socket?

@ViniGodoy - Lattes

Tem dúvidas de Java? Poste no fórum! Não respondo dúvidas de java via MP!

Ponto V! - Desenvolvimento de Jogos Profissional - @Pontov - Facebook
Projeto Towel - Swing de uma forma inteligente (Novo lar do ObjectTableModel e do Auto-Filtro).

Ei... você está usando DefaultTableModel no seu projeto??
Não faça isso! Veja: http://www.guj.com.br/posts/list/15/199067.java#1001295
[WWW]
filipenf
JavaBaby

Membro desde: 27/05/2009 12:47:07
Mensagens: 98
Offline

é possível sim, e não há a necessidade de ficar enviando \n nem fechar a conexão. O que deve estar acontecendo é que o SO ou a VM devem estar 'bufferizando' a saída do seu socket. Você está dando flush a cada vez que escreve ?

Você está bêbado quando começa a sentir solidariedade e não consegue pronunciar essa palavra.

Filipe N. Felisbino
SCJP - SCWCD - LPIC 1
fnf01.blogspot.com - twitter.com/filipenf
[WWW] [Yahoo!]
laudenpower
JavaEvangelist
[Avatar]

Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline

Segue o código:

Servidor


Cliente


Desde já agradeço a atenção de todos.

Enquanto cultivares teu saber, nada tens a temer!

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Você pode mudar um pouco seu protocolo? Pela minha experiência, é muito difícil fazer protocolos baseados em texto funcionar.

Normalmente é aconselhável:

- Modificar uma opção DO SOCKET ( dê uma olhada em setTcpNoDelay - você deve chamar esse método imediatamente após abrir o socket , e não depois, com o parâmetro "true" ) para que ele não bufferize a saída :
- Criar um protocolo binário que mande pacotes com cabeçalho e dados.

O cabeçalho pode ser bem simples e ter apenas o tamanho dos dados (em 2 bytes).
Por exemplo, para mandar a mensagem "abacaxi" (que tem 7 bytes), você:
a) Converte a mensagem para um array de bytes;
b) Mede o tamanho desse array;
c) Usa DataOutputStream, método writeShort, para gravar o tamanho desse array;
d) Usa DataOutputStream, método write, para mandar os outros bytes.

Para receber a mensagem, você
a) Usa DataInputStream, método readShort, para ler o tamanho do array;
b) Vai chamando repetidamente DataInputStream, método read, até receber todos os dados (de acordo com o tamanho) e acumulando os dados em um ByteArrayOutputStream. Quando receber todos os dados (ou quando read retornar -1, indicando que o socket foi fechado), a mensagem foi lida.

This message was edited 1 time. Last update was at 21/07/2009 08:44:34

[WWW]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

thingol wrote:Você pode mudar um pouco seu protocolo? Pela minha experiência, é muito difícil fazer protocolos baseados em texto funcionar.


Mesmo o HTTP, que é um protocolo baseado em texto, também trabalha com tamanhos de mensagens (o tal do Content-Length).
[WWW]
laudenpower
JavaEvangelist
[Avatar]

Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline

thingol wrote:Você pode mudar um pouco seu protocolo? Pela minha experiência, é muito difícil fazer protocolos baseados em texto funcionar.

Tipo nesse caso minha inexperiencia me deixa na mão a principio eu tenho que mandar uma mensagem para o servidor e nada mais (tipo não preciso receber nada do mesmo), mas sendo assim você poderia me mandar um link exemplificando a criação de tal protocolo?

Desde já agradeço muito a todos que dedicaram a sua atenção.
Tchello
GUJ Master
[Avatar]

Membro desde: 07/06/2008 14:41:04
Mensagens: 1693
Online

thingol, um protocolo em xml não seria interessante?
Mesmo que o projeto seja para fins didáticos seria algo que eu mesmo gostaria muito de implementar.

Sim, já fiz um projeto onde havia um protocolo de texto, foi um horror.
Pelo menos o componente responsável em administrar as conexões dos sockets ficou muito satisfatório =D, taí um projeto que eu gostaria de fazer novamente com meus conhecimentos atuais, ficaria muito mais interessante ^^
Desculpem-me pela divagação, é apenas a nostalgia em atacando =(

Abraços!
Tchello
GUJ Master
[Avatar]

Membro desde: 07/06/2008 14:41:04
Mensagens: 1693
Online

lol, ao postar aqui o GUJ lançou um SocketException hehehehehe
laudenpower
JavaEvangelist
[Avatar]

Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline

Tchello wrote: thingol, um protocolo em xml não seria interessante?
Mesmo que o projeto seja para fins didáticos seria algo que eu mesmo gostaria muito de implementar.

Sim, já fiz um projeto onde havia um protocolo de texto, foi um horror.
Pelo menos o componente responsável em administrar as conexões dos sockets ficou muito satisfatório =D, taí um projeto que eu gostaria de fazer novamente com meus conhecimentos atuais, ficaria muito mais interessante ^^
Desculpem-me pela divagação, é apenas a nostalgia em atacando =(

Abraços!


É que na verdade eu apenas preciso enviar uma string de tamanho 10, nada mais tipo eu estou usando o DataInputStream e o DataOutputStream para enviar as informações do cliente e ler elas no servidor, o que acontece é que não tem jeito do servidor ficar lendo a medida que vou enviando, o servidor processa o que o cliente manda apenas quando o mesmo fecha a conexão.
Você teria algum exemplo de como fazer essa comunicação, mantendo o socket do cliente aberto.

Desde já agradeço a atenção

This message was edited 1 time. Last update was at 21/07/2009 13:04:21


Enquanto cultivares teu saber, nada tens a temer!

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Thingol wrote:
- Modificar uma opção DO SOCKET ( dê uma olhada em setTcpNoDelay - você deve chamar esse método imediatamente após abrir o socket , e não depois, com o parâmetro "true" ) para que ele não bufferize a saída :


Você leu o que escrevi? Vou repetir.

Em caso de dúvida:

http://articles.techrepublic.com.com/5100-10878_11-1050878.html
[WWW]
laudenpower
JavaEvangelist
[Avatar]

Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline

thingol wrote:
Thingol wrote:
- Modificar uma opção DO SOCKET ( dê uma olhada em setTcpNoDelay - você deve chamar esse método imediatamente após abrir o socket , e não depois, com o parâmetro "true" ) para que ele não bufferize a saída :


Você leu o que escrevi? Vou repetir.

Em caso de dúvida:

http://articles.techrepublic.com.com/5100-10878_11-1050878.html


Nesse caso é após a criação do socket no cliente? Eu li o que foi escrito porém quando eu chamo o método setTcpNoDelay(true); não acontece nada. Li o conceito sobre os método TCP_NODELAY e TCP_CORK, até onde eu pude entender quando eu configuro o meu socket para um desses o mesmo não espera que o cabeçalho do pacote seja enviado antes. Mas nesse caso não estou entendendo como eu tenho que chamar o método imediatamente após abrir o socket, vou postar o código que comecei do zero para os colegas avaliarem melhor.

Servidor



Cliente



Desculpa se não entendi direito algumas coisas, mas estou acompanhando esse tópico com o máximo de atenção para não disperdiçar o tempo de ninguém.

Desde já agrdeço pela atenção.
filipenf
JavaBaby

Membro desde: 27/05/2009 12:47:07
Mensagens: 98
Offline

não vejo problema nenhum quanto à usar o protocolo texto. Temos uma aplicação aqui que conecta à um servidor feito em C++ e transfere dados em modo texto sem problema. Existe uma opção para utilizar texto-plano ou criptografado, e nunca tive nenhum problema com isso. Pelo que entendi o problema é buffer, só não sei se no client ou no servidor.

Se você tiver acesso à uma máquina com linux, sugiro você usar o netcat pra emular o seu servidor, desta forma você consegue verificar se o problema é realmente o client. Basta você digitar

netcat -l -p 20000

e depois apontar o seu client para essa máquina. Com o uso do netcat, tudo que entrar por essa porta será impresso na stdout. Se não aparecer nada, o problema está no seu client. Se aparecer, o problema está no seu server.

Você está bêbado quando começa a sentir solidariedade e não consegue pronunciar essa palavra.

Filipe N. Felisbino
SCJP - SCWCD - LPIC 1
fnf01.blogspot.com - twitter.com/filipenf
[WWW] [Yahoo!]
 
Índice dos Fóruns » Java Avançado
Ir para:   
Powered by JForum 2.1.8 © JForum Team