Newsgroup: it.comp.java
Titolo: [SEMI OT] tcp ip

volevo imparare come far comunicare due programmi via tcp e qui iniziano i
problemi.
gli esempi in rete sono piu' o meno tutti del tipo "per fare una chat si
fa cosi' e cosi'". la maggior parte degli esempi trattano di udp, il resto
serve a poco, i messaggi chat sono sempre corti, e un datagramma ethernet
li contiene agevolmente (anche se non spiegano mai che se mando due
messaggi di fila e il programma che li riceve e' lento o fa delle
elaborazioni, puo' capitare che il ricevente si trovi un unico "pacchetto"
contenente tutti e due i messaggi concatenati), ma a me piace capire le
cose a fondo, quindi vi chiedo come si crea un programma "vero" di
comunicazione tcp.
mettiamo il caso che devo trasmettere un messaggio da 1 mb da un pc
all'altro.
posso inviare tutto in una botta sola (lasciando il compito di spezzarlo
al layer tcp), o devo comunque spezzarlo in piu' invii dal mio programma?
e se fosse cosi', siamo sicuri che il primo messaggio arrivi sempre (anche
teoricamente) prima del secondo, o e' possibile in qualche remoto caso,
che il primo faccia un giro tra router piu' lungo, e arrivi dopo? 
e visto che inviando piu' pacchetti distinti (cioe' non che riguardano lo
stesso gruppo di dati, un po' come un invio di messaggi di chat) il
ricevente legge uno stream, c'e' un modo per sapere dove inizia e dove
finisce un pacchetto, o devo gestirmi io il problema, inserendo in testa
al pacchetto la sua lunghezza?
e via dicendo. mi sapete dare un link (in italiano, se possibile) che
tratti di programmazione "seria" in tcp?
grazie
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 writes:
M> mettiamo il caso che devo trasmettere un messaggio da 1 mb da un pc
M> all'altro.  posso inviare tutto in una botta sola (lasciando il
M> compito di spezzarlo al layer tcp), o devo comunque spezzarlo in
M> piu' invii dal mio programma?
Se riesci agevolmente a gestire  buffer da 1 mega... Teoricamente puoi
farlo, non č detto che sia il modo piů efficiente.
M>  e se fosse cosi', siamo sicuri che
M> il primo messaggio arrivi sempre (anche teoricamente) prima del
M> secondo,
Se non ricordo  male TCP dovrebbe garantire lui  la cosa (a differenza
di UDP).
M> c'e' un modo per sapere dove inizia e dove
M> finisce un pacchetto,
Credo che la cosa sia a livello di IP, non di TCP.
M> o devo gestirmi io il problema, inserendo in
M> testa al pacchetto la sua lunghezza?
A che scopo ? Se hai  bisogno di un qualcosa di tipo "inizio messaggio
- fine  messaggio"  questo  č  un  problema ad  un  livello  superiore
rispetto a TCP.
Oltretutto tu  parti con una MTU di  X, ad un certo  punto si transita
per un ramo con una MTU di X/2, il tuo pacchetto viene spezzato...
M> un link (in italiano, se possibile) che tratti di programmazione
M> "seria" in tcp?
Meglio la libreria. Se trovi le edizioni italiane di Internetworking
with TCP/IP di Comer.
-- 
 /\            ___
/___/\__|_|\_|__|___Gian Uberto Lauri_____________________
  //--\ | | \|  |   Integralista GNUslamico  
\/		    e allevatore di bug da competizione

Ho lavorato in modo abbastanza massiccio su questa particolare
problematica.
Ti sintetizzo in breve le conclusioni a cui sono giunto:
1) Il problema non è il protocollo quanto il fatto che la app che sta
dall'altro lato deve avere il TEMPO di leggere il pacchetto che è
stato inviato
Ergo, conviene dividere il msg in pacchetti e prevedere un sistema di
"etichettatura" di questi pacchetti in modo da permettere a chi li
riceve di rimettere insieme il puzzle
2) Per etichettare un pacchetto di dati devi eslcudere a priori
l'indirizzo ip.
Se 6 su una rete aziendale molti pc potrebbero "uscire" con lo stesso
ip
3) Non so su altre piattaforme, ma su windows il socket non si accorge
se il collegamento tcp/ip a basso livello è stato chiuso
Ho riscontrato che se apri un socket sun una specifica porta tra 2 host
connessi a internet, se per un po non viaggia manco un bit, il canale
viene chiuso.
Questa casistica puo' essere gestita in vari modi.
Io ho optato per un pacchetto fake da inviare ogni n unità di tempo
dopo le quali non viene inviato alcun dato giusto per tenere attiva la
linea.
Ovviamente, se hai un adsl questa soluzione è ok, ma se hai una isdn
va eslcusa a priori per problemi di costo.
4) Compressione, compressione e ancora compressione.
5) Il buffer del tcp/ip è di 4k.
Quindi, se devi dividere il msg in + pacchetti, ti conviene tenere
conto di questo parametro.
6) Se sviluppi una gerarchia di classi per gestire tutto questo circo
devi stare molto attento a come la progetti. Meglio avere 10 classi e
smadonnare per farle lavorare insieme che avere 2 classi che potrebbero
risultare + comode
7) Java non so, ma su .net il namespace che contiene classi e
interfacce per gestire questa problematica è progettato molto bene.
Quindi, puoi darglu un occhio e prendere spunto da li per farti un
idea.
8)  se in java esiste un namespace dedicato e mi dite il nome sono
contento... :-))
baiBai
AS

 AS

 5) Il buffer del tcp/ip è di 4k.
Imho opinabile. Potrebbe esserlo come no, dipende dalla congestione e 
dalla dimensione negoziata della sliding window. Credo sia pure 
dipendente dall'OS.
Saluti
CarMas

 sul canale non chiude la socket.
Io non discuto la teoria.
Non sono esperto di queste cose, ma posso garantirti per esperienza
diretta, personale, sul campo, che questa cosa mi è successa.
Altrimenti, che me ne fotteva di inviare pacchetti fake a scadenza
fissa?? :-|
AS

 Anche java
Avevo ben pochi dubbi, sai? ;-))
AS

TCP serve proprio per fare in modo che i dati arrivino tutti e in
ordine.
usando tcp tu non vedi pacchetti, ma un flusso di byte.
tutto cio che devi fare è leggere dal socket il flusso di byte,
fermando la lettura quando il flusso di byte è finito.
quando finisce il flusso di byte non c'è modo di saperlo, dipende dal
protocollo.
ad esempio se il protocollo è ftp, per ricevere un comando devi
continuare a leggere fin quando non trovi l'accapo. quando trovi
l'accapo sai che devi smettere di leggere.
Spero di essere stato chiaro!

 with TCP/IP di Comer.
mille grazie! :)


 contento... :-))
intanto.. si chiama "package" e non "namespace"
comunque:
 
 
java.net
-- 
Pietro
(\_/)  <- This is Bunny.
(°_°)     Copy Bunny into your signature to help
(> <)     him on his way to world domination.

> differenza di UDP).
M> anche su invii diversi?  cioe', io invio un messaggio CIAO.  dopo
M> invio un messaggio CIAO2.  sono perfettamente sicuro che ciao
M> arrivi prima di ciao2 o visto che sono due invii indipendenti,
M> ciao2 potrebbe arrivare prima?
Se sono all'interno della stessa connessione CIAO sarà davanti a CIAO2
M> no, inteso cosi'.  io invio CIAO. poi invio CIAO2.  il ricevente
M> non sa quant'e' lungo il msg.  sulle api di win la ricezione
M> funzionava come stream, in pratica se non scarico abbastanza
M> velocemente, il buffer veniva accodato con il secondo invio:
Se non ricordo male TCP lavora come stream.
M> ecco, in questo caso, come faccio a capire dove comincia il secondo
M> msg?
Come ti hanno detto, è un problema "a livello di applicazione".
TCP ti trasferisce i dati e ti dice che il flusso è stato chiuso. Come
interpretare i dati che arrivano è compito dell'applicazione
Per esempio SMTP  (quello della posta), al momento  in cui comincia la
trasmissione dei dati considera come  fine messaggio il trovare un '.'
solo soletto ad inizio riga.
Idem, se non ricordo male POP.
Altri hanno altri modi, a qualche protocollo - che si attende una sola
risposta - basta la  chiusura della comunicazione come delimitatore di
fine messaggio.


Mi cospargo il capo di cenere e facco ammenda.
Mi avete detto un sacco di cose interessanti che ho intenzione di
sviscerare a fondo, sviluppando qualcosa in java che faccia questo tipo
di cose.
Cosi metto in pratica quanto ho appreso da voi sul tcp/ip e intanto
inizio a scrivere qualcosa in java.
Un saluto a tutti e grazie.
AS

ottimo, grazie a tutti


[cut]
Se vuoi imparare effettivamente come funzioni lo stack tcp/ip, allora:
1. Documentati per bene sul funzionamento dei due protocolli
2. Lascia perdere java per fare i tuoi esperimenti, non ti può insegnare
    nulla in tale campo questo linguaggio
 > mettiamo il caso che devo trasmettere un messaggio da 1 mb da un pc
 > all'altro.
 > posso inviare tutto in una botta sola (lasciando il compito di
 > spezzarlo
 > al layer tcp), o devo comunque spezzarlo in piu' invii dal mio
 > programma?
Se ti poni ad usare un protocollo sopra tcp, o anche tcp raw senza 
nessuna formattazione di messaggio puoi fare come vuoi...non cambia niente
 >e se fosse cosi', siamo sicuri che il primo messaggio arrivi sempre 
 >(anche
 >teoricamente) prima del secondo, o e' possibile in qualche remoto caso,
 >che il primo faccia un giro tra router piu' lungo, e arrivi dopo?
 >e visto che inviando piu' pacchetti distinti (cioe' non che riguardano >lo
 >stesso gruppo di dati, un po' come un invio di messaggi di chat) il
 >ricevente legge uno stream, c'e' un modo per sapere dove inizia e dove
 >finisce un pacchetto, o devo gestirmi io il problema, inserendo in 
 >testa al pacchetto la sua lunghezza?
Se usi tcp non hai la sicurezza che se te mandi un messaggio A, che lo 
stack splitta in 3 messaggi a-b-c, questi arrivino al destinatario nello 
stesso ordine...e francamente non ti interessa neanche; quello che tcp 
ti garantisce è che il messaggio in arrivo non sarà processato dai 
protocolli di livello superiore finchè non sia stato ricostruito (se ad 
esempio l'ordine di arrivo è b-c tali dati non saranno processati sullo 
stack finchè il pacchetto a non sia giunto e messo al giusto posto).
Se parli di stream non ha senso parlare di lunghezza...comunque no non 
c'è modo di sapere la "fine" di un pacchetto, anche se questa è 
raramente utile. Resta il fatto che puoi sceglierti il formato dei 
pacchetti che invii, quindi il primo campo potrebbe ad esempio essere un 
intero che contiene la lunghezza in byte del payload
 >mi sapete dare un link (in italiano, se possibile) che
 >tratti di programmazione "seria" in tcp?
Un link no, ti posso dare il nome di un gran libro (in inglese però), 
che tratta approfonditamente questi argomenti
TCP-IP illustrated
di Stevens
Ciao, Alberto

 grazie
In questo momento non posso acedere al web ma basta googlare "tcp/ip", "tcp 
tutorial" e via dicendo... troverai tonnellate di informazioni. 

 conto di questo parametro.
Non necessariamente. Il buffer è un parametro variabile gestito da TCP in 
quella fase denominata "windowing". A meno che non programmi a basso livello 
questi sono parametri di cui non ti devi preoccupare, in genere.
Un pacchetto che dovrà trasportare un buffer di 10 byte non verrà 
frammentato, un pacchetto che dovrà trasportare un buffer di 10.000 byte 
(sparo a caso) potrà essere frammentato, a seconda da cosa decide TCP, in 20 
pacchetti da 500 bytes l'uno, ad esempio

 writes:
b> Se mandi due pacchetti il socket ricevente ne riceverà due.
Può capitare che vengano frammentati durante il viaggio...


 Può capitare che vengano frammentati durante il viaggio...
A quanto ne so io la frammentazione dei pacchetti dovrebbe essere decisa dal 
socket che li spedisce e da lui soltanto.
Questa "frammentazione durante il viaggio" di cui parli da chi dovrebbe 
essere messa in pratica? Dai routers?

> Può capitare che vengano frammentati durante il viaggio...
b> A quanto ne so io la frammentazione dei pacchetti dovrebbe essere
b> decisa dal socket che li spedisce e da lui soltanto.  Questa
b> "frammentazione durante il viaggio" di cui parli da chi dovrebbe
b> essere messa in pratica? Dai routers?
Esatto.
Mettiamo il caso che uno dei rami attraversati dal pacchetto abbia una
MTU  minore  dell'originaria.   In   quel  caso  i  pacchetti  vengono
frammentati  prima  di venire  instradati  e  giungono a  destinazione
frammentati.


 frammentati.
Gia vero. Dimenticavo MTU.