PDA

View Full Version : Trasferire su rete IP dati tra applicazioni diverse


dupa
29-04-2006, 13:51
Ho una situazione del tipo:

app1 su host1: scritta in C# .NET (o un qualsiasi altro linguaggio)
app2 su host2: scritta in Java SE (o un qualsiasi altro linguaggio)

L'applicazione Java ha, ad esempio dei dati in questa forma:

dato {
campo1 (numerico, es: 8)
campo2 (stringa, es: "ciao")
campo3 (dati binari, es: un file JPG)
}

Il mio obiettivo è
- leggere da disco (o da dove si vuole) questo dato dall'applicazione Java
- serializzarlo
- trasferirlo su TCP/IP
- deserializzarlo
- scrivere su disco (o dove si vuolo) questo dato dall'applicazione C#

Se non ho capito male il senso sarebbe di costruire sopra il TCP un mio formato header+payload (noto a tutte le applicazioni che gireranno su rete).

Ora da quel che ho letto sembrerebbe che tramite SOAP si possa fare qualcosa del genere.
In pratica si impacchetta il proprio dato in un XML, che viente a sua volta impacchettato in un "envelope" SOAP.
A questo punto l'envelope SOAP viene spedito in rete facendolo viaggiare ad esempio su HTTP/TCP/IP e così via.

La cose che mi lasciano perplesso sono:

1) perchè SOAP scomoda HTTP (o SMTP o altro..)? non è possibile costruire lo stream del XML e gettarlo in uno stream TCP direttamente?

2) ho visto che per inserire dati binari nell'XML serve usare MIME, è realmente altrimenti impossibile ficcare dati binari in un XML, ci sono altre vie?

3) esistono vie alternative più semplici? il mio obiettivo sembra essere abbastanza semplice: trasferire dati composti da stringhe, numeri e file binari tra applicazioni diverse.

Stiwy.NET
03-05-2006, 17:39
Ciao... ammetto che non ho capito il 100% delle cose che hai scritto, però provo a rispondere... giusto perchè non so cosa fare!
Io qualche settimana fa mi sono scritto una dll in VB.NET che fa uso dei Socket... In teoria per testare questa dll ho fatto una chat che avviata su 2 macchine mi avrebbe permesso di comunicare da una all'altra... purtroppo però ogni mio tentativo di test è fallito. Non ho mai potuto provare la correttezza di ciò che ho scritto perchè quì in azienda siamo sommersi da firewall e non so se il problema sia per una sbagliata sintassi del codice o un blocco del firewall.
Indi... se vuoi ti potrei passare questa dll (e source)... la puoi provare con c#.net incorporandola con una tua applicazione. In teoria io nella chat passavo solo stringhe, ma nulla vieta il passaggio di dati binari...

dupa
03-05-2006, 18:16
Ciao... ammetto che non ho capito il 100% delle cose che hai scritto, però provo a rispondere... giusto perchè non so cosa fare!
Io qualche settimana fa mi sono scritto una dll in VB.NET che fa uso dei Socket... In teoria per testare questa dll ho fatto una chat che avviata su 2 macchine mi avrebbe permesso di comunicare da una all'altra... purtroppo però ogni mio tentativo di test è fallito. Non ho mai potuto provare la correttezza di ciò che ho scritto perchè quì in azienda siamo sommersi da firewall e non so se il problema sia per una sbagliata sintassi del codice o un blocco del firewall.
Indi... se vuoi ti potrei passare questa dll (e source)... la puoi provare con c#.net incorporandola con una tua applicazione. In teoria io nella chat passavo solo stringhe, ma nulla vieta il passaggio di dati binari...

Ciao, se la puoi postare mi fai un favore :D è sempre materiale in più.

Comunque ho già visto in Java vari esempi di applicazioni su TCP/IP dove buttano solo stringhe nello stream.
A me serviva qualcosa di semplice per mettere in modo "ordinato" sia numeri che stringhe che dati binari.

ad esempio

primo byte identifica il messaggio:
0x10 = request
0x20 = reply
secondo e terzo byte identificano lunghezza messaggio
ecc. ecc.

Insomma.. costruire una sorta di "struct". che poi sia utilizzabile sia con client C# che Java che C++ o qualunque altra cosa.

Stiwy.NET
03-05-2006, 18:50
Ciao, se la puoi postare mi fai un favore :D è sempre materiale in più.

Comunque ho già visto in Java vari esempi di applicazioni su TCP/IP dove buttano solo stringhe nello stream.
A me serviva qualcosa di semplice per mettere in modo "ordinato" sia numeri che stringhe che dati binari.

ad esempio

primo byte identifica il messaggio:
0x10 = request
0x20 = reply
secondo e terzo byte identificano lunghezza messaggio
ecc. ecc.

Insomma.. costruire una sorta di "struct". che poi sia utilizzabile sia con client C# che Java che C++ o qualunque altra cosa.
Mmmm ho capito... prima che riesca a mettere il codice on line credo che ci vorranno 24, quindi spero che tu non abbia fretta.
Kmq... se ti serve una struttura secondo me è più comodo se te la costruisci tu. Io con la mia dll l'ho fatto: i primi 4 caratteri identificano se sto facendo il test di connessione, se invio una stringa o se è un file... nel receiver gestisco quindi separatamente le informazioni...

fabianoda
04-05-2006, 08:57
Il problema nel trasferimento via TCP non esiste, anche se usi linguaggi diversi.

Forse (ripeto forse, perché non ho mai provato) è il discorso della serializzazione. Qua dubito che un oggetto serializzato in Java possa essere deserializzato e compreso in VB.NET o comunque da un altro linguaggio, ma non ci giurerei..

Stiwy.NET
04-05-2006, 20:06
Come promesso ho messo il file zip del progetto che ho creato usando i socket del framework...
Scarica quà il file TestSocket.zip (http://www.lostronzo.it/public/stefano/forum/testsocket.zip)
Boh, spero ti possa essere d'aiuto.

Ho solo una domanda... perchè ti interessa tanto far "colloquiare" due applicazioni fatte con linguaggi diversi?

^TiGeRShArK^
04-05-2006, 23:36
Ciao, se la puoi postare mi fai un favore :D è sempre materiale in più.

Comunque ho già visto in Java vari esempi di applicazioni su TCP/IP dove buttano solo stringhe nello stream.
A me serviva qualcosa di semplice per mettere in modo "ordinato" sia numeri che stringhe che dati binari.

ad esempio

primo byte identifica il messaggio:
0x10 = request
0x20 = reply
secondo e terzo byte identificano lunghezza messaggio
ecc. ecc.

Insomma.. costruire una sorta di "struct". che poi sia utilizzabile sia con client C# che Java che C++ o qualunque altra cosa.
mmmm..
non so se ho capito bene..
ma mi pare di aver compreso ke a te serve passare dei dati via tcp, non degli oggetti serializzati...
Per fare questo immagino sia sufficiente aprire un socket e inviare i dati nello stream. facendoti mandare un ack dall'altra apllicazione appena ha ricevuto tutto...
non è la cosa + efficiente, ma è la + semplice ke mi è venuta in mente....
in questo modo ad esempio manderesti da un applicazione la stringa nello stream TCP e una volta ke l'hai ricevuta ti potresti far mandare ok.
A questo punto procedi con l'immagine JPG, e così via..
alla fine tramite TCP viaggiano stringhe o array di byte per gli oggetti + complessi e quindi non dovresti avere alcun problema a ricomporre i dati ricevuti dall'altra parte.
Non c'è neanke bisogno che ti occupi di ritrasmissioni e cose del genere perkè fa tutto il protocollo TCP.
Per java ti posso dire che ti servono le classi Socket e ServerSocket e i metodi toByteArray (mi pare) delle varie strutture dati se non hai già a disposizione l'array di byte..
Per C# non ho idea ma immagino ci sia un meccanismo molto simile, dato che per molti versi è piuttosto uguale a java.
L'unica cosa è che forse ti conviene mandare inizialmente una Stringa che descrive il tipo di dato che stai inviando cosicchè l'atra applicazione può convertire l'array di byte nelo formato giusto.
Spero di non aver dimenticato niente e di essermi spiegato :p
se hai problemi kiedi pure ;)

P.S. ovvviamente non ho mai usato SOAP e qdi non ho idea se in quel modo ci sia un modo + facile per scambiarsi i dati..
immagino di si, ma km ho già detto, anke se c'è, non lo conosco :D

dupa
04-05-2006, 23:58
Come promesso ho messo il file zip del progetto che ho creato usando i socket del framework...
Scarica quà il file TestSocket.zip (http://www.lostronzo.it/public/stefano/forum/testsocket.zip)
Boh, spero ti possa essere d'aiuto.

Ho solo una domanda... perchè ti interessa tanto far "colloquiare" due applicazioni fatte con linguaggi diversi?

Grazie mille! appena il lavoro mi lascia un momento libero me lo studio!

Mi interessa far colloquiare applicazioni scritte in linguaggi diversi perchè voglio scrivere un'applicazione Peer2Peer, io scriverò il mio client in Java e definirò come saranno strutturati i pacchetti che invio sopra TCP/IP o UDP/IP, poi se eventualmente avrò voglia un domani potrò scrivere un'applicazione C# (o C++ o altro) che si interfaccia alla mia rete peer2peer o se qualcuno vorrà scrivere un'applicazione nel linguaggio che preferisce potrà agganciarsi alla mia rete peer2peer scrivendo il suo client, gli basterà semplicemente rispettare la "convenzione" che avrò io definito per i messaggi. intesi come header+payload.

dupa
05-05-2006, 00:00
Il problema nel trasferimento via TCP non esiste, anche se usi linguaggi diversi.

Forse (ripeto forse, perché non ho mai provato) è il discorso della serializzazione. Qua dubito che un oggetto serializzato in Java possa essere deserializzato e compreso in VB.NET o comunque da un altro linguaggio, ma non ci giurerei..

Sì infatti, non intendo usare le funzioni "build-in" di serializzazione e deserializzazione di oggetti

La mia applicazione dovrà semplicemente inviare messaggi composti da "numeri", "stringhe" e "file binari".
Per i numeri e i file binari non dovrebbero esserci problemi di compatibilità, l'unico casino credo che potrebbe saltar fuori con i vari encoding delle stringhe.

dupa
05-05-2006, 00:05
Per fare questo immagino sia sufficiente aprire un socket e inviare i dati nello stream. facendoti mandare un ack dall'altra apllicazione appena ha ricevuto tutto...
non è la cosa + efficiente, ma è la + semplice ke mi è venuta in mente....
in questo modo ad esempio manderesti da un applicazione la stringa nello stream TCP e una volta ke l'hai ricevuta ti potresti far mandare ok.



Bè in realtà TCP dovrebbe già di suo garantire l'invio completo dello stream, senza bisogna dell'ack (in pratica l'ack è già incorporato in TCP stesso)


L'unica cosa è che forse ti conviene mandare inizialmente una Stringa che descrive il tipo di dato che stai inviando cosicchè l'atra applicazione può convertire l'array di byte nelo formato giusto.



Io contavo di usare codicini esadecimali per descrivere il messaggio che viaggia su TCP.
Esempio se il primo byte del messaggio è "0x10" allora il messaggio è una file request.
Se nel secondo byte di quel messaggio c'è "0x08" vuol dire che il nome del file che chiedo è lungo 8 caratteri.
E quindi nei successivi byte del messaggio ci son gli 8 caratteri con il nome del file richiesto..
(è solo per fare un esempio)



P.S. ovvviamente non ho mai usato SOAP e qdi non ho idea se in quel modo ci sia un modo + facile per scambiarsi i dati..
immagino di si, ma km ho già detto, anke se c'è, non lo conosco :D

Bè SOAP è molto figo, solo che mi pare di aver capito che aggiunge molto overhead e nel caso di un'applicazione peer2peer come voglio fare io, è indispensabile buttare via meno spazio possibile.

pinok
05-05-2006, 09:09
Vediamo se posso darti qualche idea.... ;)

Ho una situazione del tipo:
1) perchè SOAP scomoda HTTP (o SMTP o altro..)? non è possibile costruire lo stream del XML e gettarlo in uno stream TCP direttamente?

2) ho visto che per inserire dati binari nell'XML serve usare MIME, è realmente altrimenti impossibile ficcare dati binari in un XML, ci sono altre vie?

3) esistono vie alternative più semplici? il mio obiettivo sembra essere abbastanza semplice: trasferire dati composti da stringhe, numeri e file binari tra applicazioni diverse.

1) Puoi benissimo aprirti un socket diretto e buttare il documento XML sullo stream, nulla ti vieta di farlo; se vuoi limitare lo spreco di banda, creati dei tag ridotti. L'uso di XML ti consente di usare le librerie esistenti sia per scrivere che per leggere il documento, senza inventare niente e rendendo il tutto più gestibile. L'overhead dei tag, soprattutto se incapsuli dati binari, è minimo...
Per ridurre ulteriormente, metti stringhe e numeri come attributi e solo il file binario come elemento.

2) Potresti usare qualche funzione che faccia l'uuencode in trasmissione e uudecode in ricezione (praticamente trasforma un file binario in un testo esadecimale)

3) Più semplici non saprei (non credo), però potrebbe esserci CORBA (tanto per sapere che esiste ;)), però non ho mai avuto occasione di usarlo.

dupa
05-05-2006, 09:25
Vediamo se posso darti qualche idea.... ;)



1) Puoi benissimo aprirti un socket diretto e buttare il documento XML sullo stream, nulla ti vieta di farlo; se vuoi limitare lo spreco di banda, creati dei tag ridotti. L'uso di XML ti consente di usare le librerie esistenti sia per scrivere che per leggere il documento, senza inventare niente e rendendo il tutto più gestibile. L'overhead dei tag, soprattutto se incapsuli dati binari, è minimo...
Per ridurre ulteriormente, metti stringhe e numeri come attributi e solo il file binario come elemento.

2) Potresti usare qualche funzione che faccia l'uuencode in trasmissione e uudecode in ricezione (praticamente trasforma un file binario in un testo esadecimale)

3) Più semplici non saprei (non credo), però potrebbe esserci CORBA (tanto per sapere che esiste ;)), però non ho mai avuto occasione di usarlo.


1) sì per le stringhe e i numeri può andar bene, ma ho visto che ad esempio SOAP che usa l'approccio di inviare i dati impachettati in XML per inviare i binari mi pare di aver capito che li encoda in stile MIME, e mi risulta che facendo ciò i file diventano molto più grandi

2) stesso discorso del punto 1, encondando in quel modo devo trasferire più dati

3) corba sarebbe un suicidio, tutti i client dovrebbero implementare sia client che server Corba andando a usare tutte le librerie del caso, in questo caso sarebbe meglio SOAP che è più semplice e leggero.

Ciao e grazie per la risposta.

pinok
05-05-2006, 13:19
1) sì per le stringhe e i numeri può andar bene, ma ho visto che ad esempio SOAP che usa l'approccio di inviare i dati impachettati in XML per inviare i binari mi pare di aver capito che li encoda in stile MIME, e mi risulta che facendo ciò i file diventano molto più grandi

2) stesso discorso del punto 1, encondando in quel modo devo trasferire più dati

3) corba sarebbe un suicidio, tutti i client dovrebbero implementare sia client che server Corba andando a usare tutte le librerie del caso, in questo caso sarebbe meglio SOAP che è più semplice e leggero.

Ciao e grazie per la risposta.
Per il 3 lo immaginavo ;)
Per 1 e 2, se ti preme più l'occupazione di banda e a seconda di quanti pacchetti devi trasmettere, potresti fare come al punto 1, comprimere il tutto con un algoritmo di compressione, inviare UN solo file binario, e riaprirlo dall'altra parte.

Se no puoi scrivere su un socket queste informazioni binarie che ti risolvono il tutto (in parte forse l'avevi detto):

1) int che dice il numero di dati (stringhe, numeri, e file binari trasmessi)
2) byte che specifica il tipo di dato (stringa, double, int, float, file binario)
3) long dimensione del dato
4) byte[] contenuto in byte del dato
5) GOTO 2 ;) per tot volte quanto indicato da 1 (meno 1, perché quando arrivi qua un giro l'hai già fatto :D)