Autore Topic: ServerSocket.accept() si blocca  (Letto 6584 volte)

Offline iJim

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: 0
    • Mostra profilo
ServerSocket.accept() si blocca
« il: 03 Settembre 2013, 10:47:13 CEST »
0
Ciao a tutti, sto creando una piccola app per android, e non capisco perchè la socket si blocca completamente!

Codice: [Seleziona]
waitSocket = new ServerSocket( port );
connectionSocket = waitSocket.accept();    //    SI BLOCCA

BufferedReader inFromClient = new BufferedReader( new InputStreamReader( connectionSocket.getInputStream() ) );
String notifica = inFromClient.readLine();
notifica = notifica.trim();

Offline matttt

Re:ServerSocket.accept() si blocca
« Risposta #1 il: 03 Settembre 2013, 12:34:26 CEST »
0
Ciao a tutti, sto creando una piccola app per android, e non capisco perchè la socket si blocca completamente!

Perché accept() è una funzione blocking, rimane in attesa di connessioni.
ServerSocket | Android Developers()
Le mie apps su Google Play Store:

Offline iJim

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: 0
    • Mostra profilo
Re:ServerSocket.accept() si blocca
« Risposta #2 il: 03 Settembre 2013, 13:04:05 CEST »
0
Si infatti il problema è che ho scritto una classe in java che fa da client, e cerca di connettersi alla ServerSocket!!!

Questa è la classe che faccio partire da terminale.
Codice: [Seleziona]
public static void main(String[] args) {
                Socket clientSocket;
                try {
                        phoneAddress = InetAddress.getByName(args[0]);
                        port = Integer.parseInt(args[1]);
                       
                        // connessione
                        clientSocket = new Socket( args[0], port );
                        System.out.println("Aperta socket");
                        String msg = "console";
                        BufferedWriter flussoInvio = new BufferedWriter( new OutputStreamWriter( clientSocket.getOutputStream() ) );
                        flussoInvio.write(msg);
                        flussoInvio.newLine();
                        flussoInvio.flush();
                        System.out.println("messaggio inviato");
                       
                        BufferedReader response = new BufferedReader( new InputStreamReader( clientSocket.getInputStream() ) );
                        System.out.println("Arrivato qualcosa");
                        String buffer = "";
                        String melon = "";
                        while ((buffer = response.readLine()) != null) melon += buffer;
                       
                        System.out.println(melon);
                       
                }
                catch (UnknownHostException e){ e.printStackTrace(); }
                catch (IOException e){ e.printStackTrace(); }
        }

La classe client che si connette alla ServerSocket funziona perchè l'ho provata con una classe ( sempre scritta in java e avviata da terminale ) che usa ServerSocket e funziona!!!

Quindi il problema sta proprio nel waitSocket.accept(); me ne accorgo perchè ho inserito dei Toast prima e dopo la riga di codice incriminata!!!

Offline matttt

Re:ServerSocket.accept() si blocca
« Risposta #3 il: 03 Settembre 2013, 14:04:31 CEST »
0
Usa Log.d() (di android.util) invece dei Toast. E' più affidabile (perché non sei vincolato all'UI) e pensato apposta per il debugging.
Poi i messaggi te li invia nel log di sistema che puoi vedere tramite la console di Eclipse (o tramite opportune app direttamente nel cell, come CatLog)

Il tuo client cosa fa quando cerchi di connetterti? Riesce?
Eventualmente puoi fare anche un semplice test: telnet IP PORTA
per vedere se il server è in ascolto sulla porta che ti interessa.
Le mie apps su Google Play Store:

Offline iJim

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: 0
    • Mostra profilo
Re:ServerSocket.accept() si blocca
« Risposta #4 il: 03 Settembre 2013, 17:39:24 CEST »
0
Avevo provato ad usare telnet, poi ho tentato col client scritto da me e ho lo stesso comportamento!!!
Non capisco perchè al comando accept() si blocca la socket!!!

Ecco la risposta che ricevo da telnet:
Codice: [Seleziona]
sudo telnet 95.253.237.19 1390
Trying 95.253.237.19...
telnet: connect to address 95.253.237.19: Connection refused
telnet: Unable to connect to remote host

E questa è la risposta che ricevo dalla mia classe
Codice: [Seleziona]
errore Connection refused
java.net.ConnectException: Connection refused
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:382)
        at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:241)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:228)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:431)
        at java.net.Socket.connect(Socket.java:527)
        at java.net.Socket.connect(Socket.java:476)
        at java.net.Socket.<init>(Socket.java:373)
        at java.net.Socket.<init>(Socket.java:187)
        ...

Offline matttt

Re:ServerSocket.accept() si blocca
« Risposta #5 il: 03 Settembre 2013, 17:55:57 CEST »
0
Controlla i permessi per l'app ... android.permission.INTERNET ? android.permission.ACCESS_NETWORK_STATE ?
Magari prova anche una porta tipo la 8080 (alcune porte sotto la 1024 sono riservate per servizi standard)
Le mie apps su Google Play Store:

Offline iJim

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: 0
    • Mostra profilo
Re:ServerSocket.accept() si blocca
« Risposta #6 il: 03 Settembre 2013, 18:35:12 CEST »
0
Si nel Manifest i permessi sono giusti!
Codice: [Seleziona]
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

e poi le porte che uso vanno da 1025 a 9999.
Se guardi gli errori del telnet che ho postato la porta era la 1390

Post unito: 03 Settembre 2013, 18:39:28 CEST
Dimenticavo di dire una cosa ( che penso non sia così rilevante !!!).
La mia app è MultiThread, e la ServerSocket è nel Thread secondario, ma a parte il comando accept(), funziona tutto regolarmente!!!



Post unito: 03 Settembre 2013, 18:42:08 CEST
Vedo che non sono il solo ad avere questo problema!!!
sockets - Can't use ServerSocket on Android - Stack Overflow
« Ultima modifica: 03 Settembre 2013, 18:42:09 CEST da iJim, Reason: Merged DoublePost »

Offline matttt

Re:ServerSocket.accept() si blocca
« Risposta #7 il: 03 Settembre 2013, 19:00:42 CEST »
0
Patendo da una risposta da quel post. E se provi con:
Codice (Java): [Seleziona]
ServerSocket server = new ServerSocket( myTcpPort, 0, addr );
In addr dovresti mettere l'indirizzo IP che accetta le connessioni, dovrebbe bastare 0.0.0.0 se non vuoi limitazioni per la rete locale o per altre reti.
Sempre in quella risposta dicono che altrimenti accetta solo connessioni da localhost (che comunque dovrebbe andare se hai fatto dei test col client nello stesso dispositivo...)
Le mie apps su Google Play Store:

Offline iJim

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: 0
    • Mostra profilo
Re:ServerSocket.accept() si blocca
« Risposta #8 il: 03 Settembre 2013, 19:28:22 CEST »
0
Purtroppo già avevo provato!
Ho notato una differenza: se mi collego col wifi, ottengo gli errori di prima, se invece mi collego col 3G, tutto rimane in attesa.... senza nessuna risposta.
La Socket si blocca!!!!!

Offline matttt

Re:ServerSocket.accept() si blocca
« Risposta #9 il: 03 Settembre 2013, 20:18:04 CEST »
0
La questione non è che ti si blocca il socket :)
E' che l'app rimane in attesa sull' accept() e le connessioni non arrivano...
Prova ad avviare la tua app. Lancia adb shell e poi fai netstat, così vediamo come si pone in ascolto

Le mie apps su Google Play Store:

Offline Giak

  • Utente junior
  • **
  • Post: 52
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    transformer tf101
  • Sistema operativo:
    ubuntu 12.10
Re:ServerSocket.accept() si blocca
« Risposta #10 il: 03 Settembre 2013, 21:04:44 CEST »
0
io uso un codice di questo tipo con le socket bluetooth e non ho problemi.

Codice (Java): [Seleziona]
BluetoothSocket socket = null;
                // Keep listening until exception occurs or a socket is returned
                while (true) {
                    try {socket = mmServerSocket.accept();} catch (IOException e) {break;}
                    // If a connection was accepted
                    if (socket != null) {                      
                        Log.d("debug", "SERVER thread create bluetooth socket");
                        //do work with socket
                        try {
                        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                        mmServerSocket.close();
                        } catch (IOException e) {e.printStackTrace();}
                        break;
                    }
                }

Offline matttt

Re:ServerSocket.accept() si blocca
« Risposta #11 il: 03 Settembre 2013, 21:34:50 CEST »
+1
Jim... sicuro della prova che fai?
Qui da me sembra ok.
Ho creato al volo un Thread con:
Codice (Java): [Seleziona]
@Override
public void run()
{
        Log.d( "[2]", "[BEGIN]" );
        ServerSocket socket;
        try {
                socket = new ServerSocket( 8080 );
                socket.accept();
        }
        catch( IOException e )
        {
                // TODO Auto-generated catch block
                e.printStackTrace();
        }
        Log.d( "[2]", "[END]" );
}

Poi dal browser dell'emulatore apro "http://localhost:8080/" e finisco in [END]
Forse sbagli qualcosa nei tuoi test...
Le mie apps su Google Play Store:

Offline iJim

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: 0
    • Mostra profilo
Re:ServerSocket.accept() si blocca
« Risposta #12 il: 03 Settembre 2013, 22:56:03 CEST »
0
Grazie per le risposte!
Sto iniziando a dubitare anch'io che ci sia qualcosa che non va!!!
Il fatto è che ho fatto questi test e funzionano!!!
Codice: [Seleziona]
[pc:java]ServerSocket ======== acept ======
[pc]telnet            _________= ok ======

[pc:java]ServerSocket ======== acept ======
[pc:java]ClientClass  _________= ok ======

// errori
[android]ServerSocket ======= STOP
[pc]telnet          ________= STOP

[android]ServerSocket ======= STOP
[pc:java]ClientClass ________= STOP

Il telnet quando provo a connettermi all'applicazione android non da segni di vita e l'applicazione android mi mostra tutti i messaggi dei Toast fino alla riga dove si trova accept(), dopo di che non mi mostra più niente!!!!

Vorrei provare la soluzione dell' adb shell.
Ma non so che cos'è l' adb shell.....
« Ultima modifica: 03 Settembre 2013, 22:58:52 CEST da iJim »

Offline matttt

Re:ServerSocket.accept() si blocca
« Risposta #13 il: 03 Settembre 2013, 23:10:59 CEST »
+1
2 cose:
- quando mi riferivo al telnet inizialmente ero convinto che ci fosse il telnet dentro l'emulatore, se non erro non puoi dall'esterno connetterti dentro l'emulatore stesso (almeno non in maniera semplice...) perchè sei come nattato (è praticamente una sandbox);
- adb è un utility che trovi nell'SDK ( percorso standard: \android-sdk\sdk\platform-tools ), ci entri col prompt dei comandi (in Windows, o tramite una shell su Linux), poi ad emulatore avviato scrivi:
adb shell
dopo di ciò sei dentro l'emulatore tramite una shell e puoi usare vari comandi linux (ma non il telnet, che a quanto ho visto non è disponibile nel pacchetto standard BusyBox)

In questo modo puoi fare tante prove varie.
Comodo anche con sqlite e altri comandi.
Le mie apps su Google Play Store:

Offline iJim

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: 0
    • Mostra profilo
Re:ServerSocket.accept() si blocca
« Risposta #14 il: 03 Settembre 2013, 23:33:39 CEST »
0
Grazie mille!
Comunque tutte le prove le ho fatte sul mio cellulare!
Quando lancio l'applicazione ho il cellulare attaccato al pc ed eclipse mi da la possibilità di scegliere se usare l'emulatore o se far girare l'applicazione direttamente sul cellulare ( e io scelgo questa opzione ).
La mia applicazione appena si avvia comunica ad un server i suoi dati ( ip, porta, ecc ) e poi avvia una nuova Intent dove c'è un Thread che apre la ServerSocket, io dal pc mi collego al server dove ho creato una pagina web che mi da i dati del telefono, poi apro il terminale e tramite telnet cerco di fare la connessione all'indirizzo ip e alla porta del cellulare.

Se elimino la ServerSocket, tutte le altre istruzioni funzionano sia nel Thread principale che nel Thread dove c'è la ServerSocket!


Post unito: 05 Settembre 2013, 13:03:36 CEST
Matttt volevo chiederti se hai fatto la prova anche col cellulare oltre che son il simulatore

Post unito: 05 Settembre 2013, 18:02:09 CEST
Matttt grazie per l'aiuto!
Ma inspiegabilmente adesso funziona tutto alla grande!!!!
E il bello è che io non ho fatto nessuna modifica!!
Senza un'apparente motivo prima non funzionava e adesso funziona!!!!!

Forse serviva la cosa più semplice che esiste: Il riavvio!!!!!
« Ultima modifica: 05 Settembre 2013, 18:02:09 CEST da iJim, Reason: Merged DoublePost »