| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/08/2008 13:51:07
|
thiagofesta
JavaGuru
![[Avatar]](/images/avatar/eff4ceddd4035b36233219a6ea4b889e.png)
Membro desde: 19/12/2007 10:42:11
Mensagens: 233
Offline
|
Boa tarde,
Estou com um problema em meus sockets, em resumo: lentidão.
Eu faço conexão com ele, e envio básicamente imagens, e alguns comandos curtos do protocolo que criei, acredito que a lentidão está na hora de enviar a imagem, derrepente é muito dado.
Estou utilizando socket TCP. Até mesmo na rede local fica lento, o que vocês me sugerem? Alterar meu protocolo para UDP(queria fazer isso somente se não existisse outra forma mesmo)? ou existe outra forma de compactar melhor as imagens? eu já compactei usando o gzip, eu gero um png, gero o base64 e zipo, ele diminui cerca de 50%.
Obrigado desde já!
|
"É melhor calar-se e deixar que as pessoas pensem que você é tolo, do que falar e acabar com a dúvida"
Abraham Lincoln |
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/08/2008 13:57:18
|
thingol
Moderador
Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline
|
a) Qual é a velocidade da sua rede local?
b) Você já checou se os pacotes TCP estão vindo "cheios" ou não (use um analisador de protocolo, como o Network Monitor no Windows ou o Ethereal no Linux?) Isso pode estar ocorrendo porque você está enviando os dados 1 byte de cada vez (por exemplo), em vez de usar buffers maiores.
c) E só em último caso é que é desejável ficar efetuando compressão de dados. O correto é não enviar dados que você já enviou (ou seja, áreas da tela que não foram modificadas não devem ser reenviadas).
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/08/2008 14:02:59
|
thingol
Moderador
Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline
|
E não, UDP não vai deixar seu processamento mais rápido. Ele pode ser útil se você precisa fazer um broadcast, por exemplo, mas se você simplesmente vai usar uma conexão ponto-a-ponto, é melhor usar TCP, para não ter de se matar com mensagens perdidas.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/08/2008 14:09:31
|
thiagofesta
JavaGuru
![[Avatar]](/images/avatar/eff4ceddd4035b36233219a6ea4b889e.png)
Membro desde: 19/12/2007 10:42:11
Mensagens: 233
Offline
|
thiagol:
Então, minha rede local é normal, cabeada, 10/100/1000.
Só que a conexão não é ponto a ponto, na verdade tenho uma espécia de HUB que gerencia isso, todos se conectam ao hub, depois envio os dados para o cara certo.
Usando o tcp pelo que pude notar ele envia tudo de uma vez não em byte por byte.
Na hora de enviar, eu dou um println no canal de saída enviando uma string. na hora da leitura eu faço um loop percorrendo todos o que veio do canal de entrada, e adicionando em uma string. Seria dessa forma mesmo, ou tem como otimizar isto?
Agora não se minha imagem que quero enviar é grande demais, ou se o protocolo é lento, eu só sei que UDP seria mais rápido, só que com perdas, mas tu dissestes que não é bom, que seria bom pra broadcast, mas e agora?
Obrigado
|
"É melhor calar-se e deixar que as pessoas pensem que você é tolo, do que falar e acabar com a dúvida"
Abraham Lincoln |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/08/2008 14:16:56
|
king_of_gods
JavaTeenager
Membro desde: 28/03/2007 14:28:11
Mensagens: 185
Offline
|
thiagofesta wrote:Seria dessa forma mesmo, ou tem como otimizar isto?
Coloca uma thread escutando o canal, vai evitar da sua aplicação ficar em loop. E é mais seguro.
thiagofesta wrote:Agora não se minha imagem que quero enviar é grande demais, ou se o protocolo é lento, eu só sei que UDP seria mais rápido, só que com perdas, mas tu dissestes que não é bom, que seria bom pra broadcast, mas e agora?
Começe enviando mensagens de textos como Oi, Olá, Tudo bem. Se houver uma diferença de tempo brutal, pode ser alguma coisa na rede ou na aplicação.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/08/2008 14:32:47
|
thiagofesta
JavaGuru
![[Avatar]](/images/avatar/eff4ceddd4035b36233219a6ea4b889e.png)
Membro desde: 19/12/2007 10:42:11
Mensagens: 233
Offline
|
King_of_gods:
Eu uso uma thread para ler o socket.
eu ja testei pelo telnet o meu soket como você disse, é instântaneo, não da para notar nenhuma lentidão.
Acho que é na hora de enviar as imagens...
Obrigado!
|
"É melhor calar-se e deixar que as pessoas pensem que você é tolo, do que falar e acabar com a dúvida"
Abraham Lincoln |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/08/2008 14:34:35
|
thingol
Moderador
Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline
|
Na hora de enviar, eu dou um println no canal de saída enviando uma string. na hora da leitura eu faço um loop percorrendo todos o que veio do canal de entrada, e adicionando em uma string. Seria dessa forma mesmo, ou tem como otimizar isto?
Pelamordedeus, não use sockets em "modo texto".
Repita comigo e prometa para mim: nunca mais vou usar sockets em "modo texto".
Use um DataInput/OutputStream e envie o comprimento dos dados, depois a mensagem.
Só com o fato de você ter de mandar em modo texto (e passando para Base-64) já está desperdiçando um monte de banda.
Adicionar em uma string? Com "+=" ? Isso está comendo 110% da sua CPU já que isso é um verdadeiro veneno. Use uma StringBuilder ou StringBuffer se você ainda insistir em usar strings.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/08/2008 14:52:27
|
thiagofesta
JavaGuru
![[Avatar]](/images/avatar/eff4ceddd4035b36233219a6ea4b889e.png)
Membro desde: 19/12/2007 10:42:11
Mensagens: 233
Offline
|
thiagol:
De uma olhada como é meu metódo de enviar e de receber dados:
Escrevendo no socket:
Lendo o socket:
O problema então está no meu socket, não em enviar minha imagem em base64?
|
"É melhor calar-se e deixar que as pessoas pensem que você é tolo, do que falar e acabar com a dúvida"
Abraham Lincoln |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/08/2008 15:10:38
|
thingol
Moderador
Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline
|
a) Ler um caracter de cada vez? Argh
b) Uma forma besta de enviar dados via socket é encapsulá-lo em um DataOutputStream/DataInputStream. Se você vai mandar uma imagem (um array de bytes de 1 MB por exemplo), é muito mais rápido fazer algo como:
- Mandar 4 bytes de comprimento (com writeInt
- Mandar os dados (com write
e para receber, ler os dados com readInt e read
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/08/2008 15:17:44
|
thiagofesta
JavaGuru
![[Avatar]](/images/avatar/eff4ceddd4035b36233219a6ea4b889e.png)
Membro desde: 19/12/2007 10:42:11
Mensagens: 233
Offline
|
thiagol:
Certo, mas como ficaria o meu envio?
Vou ter que dar um loop, e ir mandando cada byte? não fica muito lento assim?
E para ler seria a mesma coisa (basicamente, faz um loop e lê todos, e vai deixando em uma string?)
Obrigado pela ajuda!
|
"É melhor calar-se e deixar que as pessoas pensem que você é tolo, do que falar e acabar com a dúvida"
Abraham Lincoln |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/08/2008 15:24:48
|
thingol
Moderador
Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline
|
Não é para mandar um byte de cada vez, nem para usar essas classes que terminam com "Reader" ou "Writer".
Até indiquei quais são os métodos que você tem de usar. Não é para mandar um byte de cada vez; mande a imagem completa de uma vez.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/08/2008 15:25:03
|
KWill
Virtual Machine Man
![[Avatar]](/images/avatar/042aec9e604155f2f06c0a16c5f9ba06.jpg)
Membro desde: 18/09/2006 10:05:46
Mensagens: 609
Offline
|
Apóio a sugestão do thingol, melhor parar de usar um protocolo de controle orientado a comandos de texto. Bote um DataOutputStream numa ponta e um DataInputStream na outra ponta e fique mandando/recebendo comandos via um protocolo de controle através de writeInt, writeShort, writeLong, readInt, readShort, readLong, etc.
Inté.
|
"Só estou certo de que não possuo outras certezas" - KWill
"Não penso, mas Googlo, logo existo!" - Geração Copy-Cola |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/08/2008 15:43:17
|
thiagofesta
JavaGuru
![[Avatar]](/images/avatar/eff4ceddd4035b36233219a6ea4b889e.png)
Membro desde: 19/12/2007 10:42:11
Mensagens: 233
Offline
|
Agora entendi...
eu dou la um DataOutputStream(socket.getOutu...).write(Arraay de bytes da minha String).
Mas e a leitura, como seria? o read retorna um inteiro.
Desculpem minha ignorância, sou leigo ainda em java, sei muito pouco.
Obrigado
|
"É melhor calar-se e deixar que as pessoas pensem que você é tolo, do que falar e acabar com a dúvida"
Abraham Lincoln |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/08/2008 15:56:24
|
thingol
Moderador
Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline
|
Você lê a quantidade de bytes a serem lidos com readInt, e lê os bytes restantes com read. Por favor, leia a documentação que lhe indiquei.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/08/2008 16:14:13
|
thiagofesta
JavaGuru
![[Avatar]](/images/avatar/eff4ceddd4035b36233219a6ea4b889e.png)
Membro desde: 19/12/2007 10:42:11
Mensagens: 233
Offline
|
thiagol:
Obrigado, mas usei o metódo readLine do inputStream para capturar o que vem, pode ser?
Obrigado
|
"É melhor calar-se e deixar que as pessoas pensem que você é tolo, do que falar e acabar com a dúvida"
Abraham Lincoln |
|
|
 |
|
|