Enviar Strings e objetos( como ArrayList por exemplo) por Socket

21 respostas
L

Pessoal, tenho uma comunicação cliente-servidor aqui feita em socket. Antes eu estava usando o objeto PrintStream encadeado a um buffer para o cliente ler mensagens do servidor e vice-versa, e o objeto PrintStream para escrever no fluxo do socket. Eu enviava apenas mensagens( String ) e não tinha problema nenhum em ler. Agora eu estou precisando enviar um ArrayList para o cliente, e o cliente precisa ler esse arrayList, como posso fazer isso? Com qual objeto e como posso identificar se é uma String que ele leu ou um objeto diferente?

Obrigado espero ter sido claro.

21 Respostas

L

Pra enviar qualquer coisa através do socket essa “coisa” precisa implementar a interface Serializable. Como a String implementa, você conseguiu mandar numa boa.
O ArrayList também implementa, porém os objetos que estão dentro dele precisam implementar a interface da mesma forma.

Tenta enviar com ObjectOutputStream e ler com ObjectInputStream. Qualquer coisa posta o código.

D

Isso :slight_smile:

L

leandronsp:
Pra enviar qualquer coisa através do socket essa “coisa” precisa implementar a interface Serializable. Como a String implementa, você conseguiu mandar numa boa.
O ArrayList também implementa, porém os objetos que estão dentro dele precisam implementar a interface da mesma forma.

Tenta enviar com ObjectOutputStream e ler com ObjectInputStream. Qualquer coisa posta o código.

Mais ai é que está, como eu vou saber se está vindo uma String ou um ArrayList na hora que eu der um ObjectInputStream.readObject(); ?

L

Se você deixar em métodos diferentes, e já “sabendo” o que vai vir, pode usar o cast.
Acho que o instance of também resolve neste caso.

V

ObjectInputStream está entre as maiores furadas quando o assunto é comunicação via socket.

O ideal é aprender a fazer direito, a começar por organizar seu protocolo:

Ou procurar APIs específicas para serialização via rede.

L

leandronsp:
Se você deixar em métodos diferentes, e já “sabendo” o que vai vir, pode usar o cast.
Acho que o instance of também resolve neste caso.

No momento não vejo alternativa deixando em método diferente. Pensei em usar instance of uma hora também mas nao consegui implementar, vou dar uma olhada no link que o vini passou e posto qualquer coisa aqui.

L

ViniGodoy:
ObjectInputStream está entre as maiores furadas quando o assunto é comunicação via socket.

O ideal é aprender a fazer direito, a começar por organizar seu protocolo:

Ou procurar APIs específicas para serialização via rede.


Muito melhor organizando o próprio protocolo mesmo!

R

leandronsp:
Pra enviar qualquer coisa através do socket essa “coisa” precisa implementar a interface Serializable. Como a String implementa, você conseguiu mandar numa boa.
O ArrayList também implementa, porém os objetos que estão dentro dele precisam implementar a interface da mesma forma.

Tenta enviar com ObjectOutputStream e ler com ObjectInputStream. Qualquer coisa posta o código.

Concordo com nosso amigo moderador…

Mas se vc estiver usando o ObjectOutputStream e quiser identificar o objeto… desserializa ele em um Object e depois de um instanceof para saber se é uma String ou um array… Lembre-se que String também é Object

L

Vou tentar dos dois jeitos para ver como que fica e ViniGodoy se eu tiver alguma dúvida em relação a criar o protocolo, crio um tópico novo ou posto lá mesmo?

L

Não consegui entender a parte de criar um protocolo no tópico que o ViniGodoy passou.

V

O que você não entendeu?

L

O que você não entendeu?

Como eu poderia implementar aquele exemplo a minha situação, onde é preciso enviar uma string e um arrayList em certos momentos. É porque é assim. É um servidor multithread. O cliente se conecta ao servidor e envia uma mensagem passando o seu nome de usuario logo que se conecta. O servidor cria uma thread assim que recebe a conexão para escutar por mensagens do cliente, e escuta a mensagem com o nome do usuario e armazena em um ArrayList de String e em um map com a chave sendo o nome do usuario e o valor sendo o fluxo de saida do usuario. Depois eu tenho que enviar esse arrayList de volta para o cliente, conforme mais clientes vão se conectando, para ele ter a relação dos usuarios que estão online. É mais ou menos isso.

V

Da mesma forma que explique lá.

Você deve organizar suas mensagens de modo a conter:

a) O tamanho da mensagem;

b) Um código, indicando o tipo da mensagem;

c) Os dados da mensagem.

Então, seu cliente não vai mais só mandar uma String. E sim, um int indicando o tamanho da mensagem. Um int com o código. Se o código for, por exemplo, 1, indica que é a String do nome que virá nos dados. Se for 2, pode indicar que é o array list.

No caso da mensagem 2, você poderia enviar:

a) Quantos elementos estão no arrayList;

b) O tamanho da String do primeiro elemento;

c) A String.

d) O tamanho do segundo

e)  e assim por diante.

Organizar o protocolo é justamente parar um tempo e pensar em que mensagens o seu sistema vai ter, e que dados essas mensagens conterão. Com isso em mãos, você saberá exatamente como enviar e como receber toda informação que você tem para trafegar.

L

ViniGodoy:
Da mesma forma que explique lá.

Você deve organizar suas mensagens de modo a conter:

a) O tamanho da mensagem;

b) Um código, indicando o tipo da mensagem;

c) Os dados da mensagem.

Então, seu cliente não vai mais só mandar uma String. E sim, um int indicando o tamanho da mensagem. Um int com o código. Se o código for, por exemplo, 1, indica que é a String do nome que virá nos dados. Se for 2, pode indicar que é o array list.

No caso da mensagem 2, você poderia enviar:

a) Quantos elementos estão no arrayList;

b) O tamanho da String do primeiro elemento;

c) A String.

d) O tamanho do segundo

e)  e assim por diante.

Organizar o protocolo é justamente parar um tempo e pensar em que mensagens o seu sistema vai ter, e que dados essas mensagens conterão. Com isso em mãos, você saberá exatamente como enviar e como receber toda informação que você tem para trafegar.

E quais objetos de fluxo eu usarei para enviar e para receber?

V

Eu usaria o DataInputStream e o DataOutputStream. Eles não são tão automágicos, mas te dão total controle.
E, no caso de fazer comunicações, é importante ter controle.

E

Protocolo é uma coisa muito boboca, se você pensar bem.

É você que está se embananando todo e achando que é uma coisa de 7 cabeças.

Uma forma bem simples de organizar um protocolo é você criar uma coleção de códigos (podem ser numéricos, por exemplo) para as perguntas e para as respostas desejadas.

Digamos que uma pergunta tenha 2 tipos de respostas, uma que é uma String, e outra que é uma lista de Strings.

Você pode indicar que a resposta do tipo 1 é uma String isolada, e a resposta do tipo 2 é uma lista de Strings.

Você pode até ter subcódigos - por exemplo, no caso da resposta do tipo 2, você pega mais um código, que é a quantidade de strings nessa lista.

E

Ou seja, nada como um pedaço de papel e lápis. Eu vejo que muita gente se embanana todo porque não consegue pôr suas idéias no papel e fica direto tentando um monte de coisas no computador. Que tal fazer alguns diagramas, hein?

L

ViniGodoy:
Eu usaria o DataInputStream e o DataOutputStream. Eles não são tão automágicos, mas te dão total controle.
E, no caso de fazer comunicações, é importante ter controle.

No javadoc do DataInputStream ou do Output diz que não é seguro para multithread. E o servidor é multithread, não teria problema?

Vocês dois poderiam me ajudar então? Vou colocando aqui o meu protocolo e vocês a medida do possível vão dizendo o que está errado, faltando, etc?

V

Praticamente nenhum stream é.

Ele só quer dizer que duas threads não podem acessar o mesmo stream ao mesmo tempo. Mas cada cliente terá seu próprio stream, então, não há acesso multi-thread sobre o stream em si.

L

Praticamente nenhum stream é.

Ele só quer dizer que duas threads não podem acessar o mesmo stream ao mesmo tempo. Mas cada cliente terá seu próprio stream, então, não há acesso multi-thread sobre o stream em si.

Então acho que não tem problema porque o que vai acontecer é uma thread acessar o DataInputStream para escutar e outra o DataOutputStream para escrever. Obrigado pela ajuda. Vou tentar colocar aqui mais ou menos como eu estou pensando no protocolo inicialmente.

S

Poderia também mandar apenas xml, contendo um nó inicial que corresponderia ao código do que está sendo transmitido. Lido esse código passar o xml para o método correspondente para fazer o parse correto, do tipo mensagem simples, ou converter tudo para um arraylist de objetos.

Criado 2 de setembro de 2012
Ultima resposta 3 de set. de 2012
Respostas 21
Participantes 7