Autore Topic: Problema Thread di ascolto UDP  (Letto 1820 volte)

Offline DocTerror

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Nexus One, G1
  • Sistema operativo:
    Ubuntu / Windows XP
Problema Thread di ascolto UDP
« il: 23 Luglio 2010, 09:23:36 CEST »
0
Buongiorno a tutti,
ho un problema che sta facendo impazzire.

Non so se ho postato nel posto giusto e nel caso spostatemi pure.

Ho un piccolo progettino che deve rimanere in ascolto sulla porta UDP(Ho seguito il tutorial su questo Forum) ma il problema è che il tutorial specificava che il Thread "Server" sarebbe rimasto in ascolto fino all'arrivo di un pacchetto ed al termine sarebbe uscito.
Sto realizzando una sorta di Chat UDP al quale tutti i telefoni che specificando una determinata porta e collegati alla rete wireless possono utilizzare.
Se cerco di mettere in loop il Thread Server mi riporta "Interuzione Imprevista"...
Non so proprio dove sbattere la testa.

Se serve posto tutto il codice o perlomeno quello del server così come è adesso.

Grazie a chiunque sia in grado di aiutarmi.
« Ultima modifica: 23 Luglio 2010, 11:16:48 CEST da Qlimax »

Offline MarcoDuff

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 1073
  • Respect: +202
    • Google+
    • marcoduff
    • Mostra profilo
    • MarcoDuff's Blog
  • Dispositivo Android:
    Samsung Galaxy Nexus
  • Play Store ID:
    MarcoDuff
  • Sistema operativo:
    Windows 7
Re:Problema Thread di alcolto UDP
« Risposta #1 il: 23 Luglio 2010, 10:29:03 CEST »
+1
Solo a livello di curiosità: perché UDP? Non è un protocollo adatto alle chat... HTTP non era meglio?

Offline DocTerror

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Nexus One, G1
  • Sistema operativo:
    Ubuntu / Windows XP
Re:Problema Thread di alcolto UDP
« Risposta #2 il: 23 Luglio 2010, 10:50:47 CEST »
0
UDP semplicemente perchè tutti i telefoni devono condividere le stesse informazioni rimanendo in ascolto tutti sulla stessa porta, Le informazioni da inviare sono minime: stringhe di testo.
 
TCP è un protocollo orientato alla connessione, pertanto per stabilire, mantenere e chiudere una connessione, è necessario inviare pacchetti di servizio i quali aumentano l'overhead di comunicazione. Al contrario, UDP invia solo i datagrammi richiesti dal livello applicativo;
Solo per questo motivo... non esiste una ragionevolità superiore ed aulica per il quale ho scelto questo protocollo...
Se avete altre idee sono in ascolto ovviamente.
Grazie

Offline DocTerror

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Nexus One, G1
  • Sistema operativo:
    Ubuntu / Windows XP
Re:Problema Thread di alcolto UDP
« Risposta #3 il: 23 Luglio 2010, 11:06:59 CEST »
0
Scusa, avevo capito "TCP"

L'HTTP non serve, L'HTTP funziona su un meccanismo richiesta/risposta (client/server): il client esegue una richiesta ed il server restituisce la risposta.

In questo caso non è un protocollo Utile.

In realtà l'applicazione al momento è solo di test ed invia stringhe ma, una volta completata permetterà a più cellulari contemporaneamente di vedere video e/o presentazioni contemporaneamente, quindi permette di non intasare la rete inviando una sola volta lo streaming.

Al momento comunque mi preme non far terminare il Thread al termine dell'arrivo del primo pacchetto.

Offline MarcoDuff

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 1073
  • Respect: +202
    • Google+
    • marcoduff
    • Mostra profilo
    • MarcoDuff's Blog
  • Dispositivo Android:
    Samsung Galaxy Nexus
  • Play Store ID:
    MarcoDuff
  • Sistema operativo:
    Windows 7
Re:Problema Thread di alcolto UDP
« Risposta #4 il: 23 Luglio 2010, 11:17:21 CEST »
+1
(Premessa: scusami tu, intendevo TCP nel mio post ed ho erroneamente scritto HTTP!!!)

A maggior ragione!  :-P

UDP semplicemente perchè tutti i telefoni devono condividere le stesse informazioni rimanendo in ascolto tutti sulla stessa porta, Le informazioni da inviare sono minime: stringhe di testo.

Questo lo fanno tutti i protocolli.
Attenzione a non confondere due concetti: numero di porta aperta per device con numero di porte aperte nel device.

In un singolo device solo una singola applicazione può restare in ascolto su una porta per protocollo. Quindi se una applicazione sul device sta in ascolto sulla porta X, un'altra applicazione non può mettersi in ascolto sulla stessa porta utilizzando lo stesso protocollo (a prescindere dal protocollo usato).

Ma quello che vuoi fare tu è diverso: tanti device (diversi) in ascolto tutti sulla stessa porta (del device). Questo è possibile con tutti i protocolli.
 
TCP è un protocollo orientato alla connessione, pertanto per stabilire, mantenere e chiudere una connessione, è necessario inviare pacchetti di servizio i quali aumentano l'overhead di comunicazione. Al contrario, UDP invia solo i datagrammi richiesti dal livello applicativo;
Solo per questo motivo... non esiste una ragionevolità superiore ed aulica per il quale ho scelto questo protocollo...

Vero che l'overhead del TCP è superiore a quello del UDP, ma è un overhead che in ogni caso devi includere!!!

Mi spiego meglio: il protocollo UDP non è orientato alla connessione, il che risulta essere più veloce ma totalmente inaffidabile: non garantisce l'arrivo dei pacchetti e non garantisce l'ordine! Devi essere tu, lato client (ovvero i device in ascolto) ad occuparti di queste problematiche o rischi (ad esempio) che il Device A mandi via chat la stringa "Ciao DocTerror, come stai?" e che il Device B riceva la stringa "stai Ciao come"!!!

Uno scenario di questo tipo (e quindi l'utilizzo del protocollo UDP) è ottimo per applicazioni che inviano streaming audio/video, dove la perdita di pochi pacchetti non è importante (perdere un singolo frame di un video streaming non impatta sul risultato finale) e dove l'ordinamento dei pacchetti è gestito dal buffer lato client.

Detto questo, a te la decisione. E' una bella sfida fare una chat in UDP, ma prima di partire progetta per bene i requisiti del tuo sistema e le problematiche associate. Se decidi di continuare, siamo qui per aiutarti nell'impresa!  ;-)

EDIT: ho appena letto la tua risposta prima del mio invio. Se la tua applicazione dopo deve aggiungere un video il mio consiglio resta: usa il TCP per la chat e l'UDP per il video (come fanno tutte le altre applicazioni del ramo!). Per quanto riguarda la soluzione del problema, mi sa che devi postarci parte del codice, tecnicamente se sei in ascolto e arriva un pacchetto il server di ascolto si sblocca. Ti basta metterti nuovamente in ascolto per riprendere.

Ciao!

Offline DocTerror

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Nexus One, G1
  • Sistema operativo:
    Ubuntu / Windows XP
Re:Problema Thread di ascolto UDP
« Risposta #5 il: 23 Luglio 2010, 11:40:58 CEST »
0
Hai ragione però al momento volevo vedere la cosa in un'altra ottica e ti ringrazio per la pazienza.
Allora, vediamo un po, posto il sorgente del threads che rimane in ascolto così è più semplice parlarne:
Attualmente utilizzo un file per l'output quindi alcune dichiarazioni servono solo come log(LogCat non ne vuole sapere di riportarmi i log e ho sistemato così).

Codice (Java): [Seleziona]
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import android.os.Environment;

public class Server implements Runnable {
        private File sd = Environment.getExternalStorageDirectory();
        private File f = new File(sd, "nome_file.txt");

        @Override
        public void run() {
                byte[] buf = new byte[17];
                DatagramPacket packet = new DatagramPacket(buf, buf.length);

            try {
                DatagramSocket socket = new DatagramSocket(10000);
                socket.receive(packet);
                write("Ricevuto: '" + new String(packet.getData()) + "'");
                socket.close();
            } catch (IOException e) {
                i++;   
                write("IO!" + i);                        
            } catch (Exception u) {
                        write("EXC!" );
            }
            run();
        }

        public void write (String Data){
        FileWriter fw = null;
        BufferedWriter bw = null;
        try{
                fw = new FileWriter(f, true);
                bw = new BufferedWriter(fw);
                bw.write(Data + "\n");
                bw.close();
                fw.close();
                run();
            }
            catch (IOException e) {      
            e.printStackTrace();
            }
        }
}

Il problema è che riceve un pacchetto, lo scrive nel file e poi per 96 volte(Int i serve solo a sapere quanti ne scriveva) mi scrive "IO!" + i (es. IO!1, IO!2, ecc.)
Quale può essere il problema? Veramente ne sto uscendo pazzo...
EDIT: Ovviamente un IOException, ma perchè?
« Ultima modifica: 23 Luglio 2010, 11:53:08 CEST da Qlimax, Reason: java syntax highlighting »

Offline DocTerror

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Nexus One, G1
  • Sistema operativo:
    Ubuntu / Windows XP
Re:Problema Thread di ascolto UDP
« Risposta #6 il: 23 Luglio 2010, 11:52:47 CEST »
0
forse ho capito perchè: perchè sono un pxxxa! :-P allora, ho rimosso dalla scrittura del file il run() che richiamava la funzione e non va più in crash. :D

All'inizio invece mi dava errore perchè non chiudevo il socket... :-\ :-\

Quindi adesso rimane in ascolto sempre.

Grazie comunque per l'aiuto, ciao!

Offline MarcoDuff

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 1073
  • Respect: +202
    • Google+
    • marcoduff
    • Mostra profilo
    • MarcoDuff's Blog
  • Dispositivo Android:
    Samsung Galaxy Nexus
  • Play Store ID:
    MarcoDuff
  • Sistema operativo:
    Windows 7
Re:Problema Thread di ascolto UDP
« Risposta #7 il: 23 Luglio 2010, 11:55:04 CEST »
+2
Penso di aver intuito il problema, ma non ne sono tanto sicuro!  :-o

Esaminiamo il codice che viene eseguito passo passo:

1. Fai partire (da qualche parte che non risulta nel codice che hai posto nel topic) la classe Runnable Server. Viene quindi eseguito il metodo run()
2. Crei la variabile buf (byte[] buf = new byte[17];)
3. Crei il DatagramPacket (DatagramPacket packet = new DatagramPacket(buf, buf.length);)
4. Apri la socket sulla porta 10000 (DatagramSocket socket = new DatagramSocket(10000);)
5. Ti metti in ascolto (socket.receive(packet);)
6. Chiami la suroutine write (write("Ricevuto: '" + new String(packet.getData()) + "'");)
7. Scrivi il file (fw = new FileWriter(f, true); bw = new BufferedWriter(fw); bw.write(Data + "\n"); bw.close(); fw.close();)
8. !!!ATTENZIONE!!! chiami run
9. ripeti i passi da 1. a 3.
10. Al passo 4 tenti di metterti in ascolto sulla porta 10000 che risulta essere occupata dalla precedente DatagramSocket (che non è stata ancora chiusa) e va tutto in eccezione!!!

Ad occhio e croce devi eliminare la chiamata a run() dentro il metodo write.
Praticamente è inutile che riapri ogni volta il server (DatagramSocket socket = new DatagramSocket(10000);), basta che cicli sul metodo receive non chiudendo mai la socket!

Facci sapere!

Offline DocTerror

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Nexus One, G1
  • Sistema operativo:
    Ubuntu / Windows XP
Re:Problema Thread di ascolto UDP
« Risposta #8 il: 23 Luglio 2010, 12:07:56 CEST »
0
Esatto, grazie!!!  ;-)

Gentilissimo e preciso.