HttpURLConnection zu SQL-DB/ASP.NET Web-API 2 auf Windows 10-Rechner

  • Antworten:9
  • OffenNicht stickyNicht beantwortet
  • Forum-Beiträge: 14

06.07.2016, 13:39:59 via Website

Hallo Leute,
für meine Android-App möchte ich gern die Speicherung von Daten in einer SQL-DB testen. Leider habe ich bisher überhaupt keine Erfahrung mit Netzwerkprogrammierung und hoffe daher sehr auf eure Hilfe.
Die SQL-DB habe ich mit VS 2015 auf dem Server (localdb)\MSSQLLocalDB angelegt. Dazu gibt es ein (bisher nicht veröffentlichtes) WebForms-Projekt mit API und Entity Framework 6. Web-API-Controller-Aktionen liefern IHttpActionResult zurück.
Im Internet Explorer erhalte ich beispielsweise bei Eingabe h ttp://localhost:9933/api/Geraets/?id=1eine Datei Geraets.json zum Download, mit einen DS der Tabelle Geraet als Antwort und die Internet Explorer Entwicklertools (F12) zeigen als Statuscode 200 / OK.
Test-Handy Nexus 5, Android-Version 4.4.2

LocalHost --> Fehlermeldung bei } catch (IOException e) {

10.0.2.2 java.net.ConnectException: failed to connect to /10.0.2.2 (port 9933): connect failed: ETIMEDOUT (Connection timed out)
127.0.0.1 java.net.ConnectException: failed to connect to /127.0.0.1 (port 9933): connect failed: ECONNREFUSED (Connection refused)
localhost java.net.ConnectException: failed to connect to localhost/127.0.0.1 (port 9933): connect failed: ECONNREFUSED (Connection refused)
sowie lt. cmd ipconfig
IPv4-Adresse java.net.ConnectException: failed to connect to /192…. (port 9933): connect failed: ETIMEDOUT (Connection timed out)
Standardgateway java.net.ConnectException: failed to connect to /192…. (port 9933): connect failed: ECONNREFUSED (Connection refused)

Mit contentXmlString = "id=1" habe ich getestet und bei LocalHost jeweils eine der Adressen angegeben:

private static String getConnection(String contentXmlString)  {
    // EingabeStream vom Server
    InputStream inputStream = null;
    // Reader, der InputStream mit der angegebenen Codierung liest
    BufferedReader bufferedReader = null;
    // StringBuilder, der aus InputStream den Stream mit den Rohdaten bildet
    StringBuilder stringBuilder = null;
    // URL für Verbindung zum Server
    URL url = null;
    // Verbindung zum Server
    HttpURLConnection urlConnection = null;
    // In diesen String werden die Daten gespeichert
    String datenXmlString = "";
    try {
        // Verbindung zum Server öffnen
        // Projekt hat Port 9933
        //
        url = new URL("h ttp://" + LocalHost + ":9933/api/geraets/?" + contentXmlString);
        urlConnection = (HttpURLConnection) url.openConnection();

        urlConnection.setRequestMethod( "POST" );

         // Dateneingabe aus der Anfrage erlauben
        urlConnection.setDoInput(true);

        // Eingabestrom zurück erhalten
       inputStream = new BufferedInputStream(urlConnection.getInputStream());
        // Wurde ein InputStream gelesen?
        if (inputStream == null) {
            // Kein Input-Stream gelesen --> Fehler --> Abbruch
            Log.e("log_tag", "Error Kein Input-Stream gelesen ");
            return null;
        }
        // zeilenweises Lesen des InputStreams mit der angegebenen Codierung
        bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        String line;
        // zeilenweises Lesen inputStream und Ergänzung Steuerzeichen
        while ((line = bufferedReader.readLine()) != null) {
            // Ergänzung der Zeile mit Zeilenumbruch (New Line)
            stringBuilder.append(line + "\n");
        }
        // InputStream schließen
        inputStream.close();
        // Konvertierung in String
        datenXmlString = stringBuilder.toString();
        // Enthielt der InputStream Daten?
        if (datenXmlString.length() == 0) {
            // Keine Daten ausgelesen, Abbruch
            Log.e(LOG, "Error Keine Daten ausgelesen ");
            return null;
        }
        Log.d(LOG, "Daten XML-String: " + datenXmlString);
    } catch (MalformedURLException e) {
        // url fehlerhaft
        Log.e(LOG, "Error in URL " + e.toString());
        e.printStackTrace();
        return null;
    } catch (IOException e) {
        // von openConnection
        // vom OutputStream, wenn dieser nicht erstellt werden kann
        // vom InputStream, wenn dieser nicht erstellt werden kann
        Log.e(LOG, "IO-Error in http connection " + e.toString());
        e.printStackTrace();
        return null;
    } catch(Exception e){
        Log.e(LOG, "Error in http connection " + e.toString());
        return null;
    }
    finally {
        // InputStream immer schließen
        if (bufferedReader != null) {
            try {
                inputStream.close();
            } catch ( IOException e ) {
                Log.e(LOG, "Error closing stream " + e.toString());
                e.printStackTrace();
            }
        }
        // urlConnection immer trennen
        if (urlConnection != null) {
            urlConnection.disconnect();
        }
    }
    // Rückgabe des String mit den Rohdaten zur Auswertung
    return datenXmlString;
}

Nun weis ich langsam nicht mehr weiter. (lightbulb) Kann mir bitte jemand helfen? Ich bedanke mich schon jetzt und finde es toll, das ihr diesen langen Eintrag gelesen habt! :)

Antworten
  • Forum-Beiträge: 14

06.07.2016, 13:44:08 via Website

Anmerkung: Damit ich, als Neuling, die Frage posten konnte, musste ich http jeweils zu h ttp ändern.;)

Antworten
  • Forum-Beiträge: 2.902

06.07.2016, 14:02:39 via Website

Hallo Bärbel,

ich stand mal vor einem ähnlichem Problem und habe dann meine "Technik" - geändert
Weshalb es nicht ging , weis bestimmt jemand anderes dazu.

Hier mal der Teil von mir , der bei mir nun läuft und dir ggf als Anhaltspunkt dienen könnte.

    // set up URL connection
     URL urlToRequest = new URL(Link);
     HttpURLConnection urlConnection = (HttpURLConnection)urlToRequest.openConnection();
     urlConnection.setDoOutput(true);
     urlConnection.setRequestMethod("POST");
     urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

     String postParameters = "vehicle=" + _current_vehicle_name +"&posdata=" + encrypted;
     Log.d(TAG, "SEND POSTDATA : CRC32(Hex) : " + Hex_CRC32 + " Length = " + String.valueOf(postParameters.length()));

     urlConnection.setFixedLengthStreamingMode(postParameters.getBytes().length);
     PrintWriter outp = new PrintWriter(urlConnection.getOutputStream());
     outp.print(postParameters);
     outp.close();

     urlConnection.connect();

     BufferedReader rd = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));

.....
.....
NACHTRAG :

Ich bin mir nicht ganz sicher , wie du deine Umgebung eingerichtet hast.

Ich würde dem Device im LAN auch mal eine feste IP zuweisen und über WLAN die connection auf die IP deines Rechners aufbauen
(ports freigeben).
Somit kannst du dir sicher sein, dass nicht dort etwas auftritt, was du nicht möchtest.

— geändert am 06.07.2016, 14:25:33

Liebe Grüße - Stefan
[ App - Entwicklung ]

B.H. R. (Androidneuling)

Antworten
  • Forum-Beiträge: 14

06.07.2016, 19:31:54 via Website

Hallo swa00,

vielen Dank für deine Hinweise. Das werde ich versuchen, bei mir umzusetzen.
Ich will aber zunächst noch deine Frage zum Einrichten der Umgebung beantworten, da ich in dem Zusammenhang keine Erfahrungen habe und es gut sein kann, das ich dort etwas falsch mache.
Da in meiner Gegend keine DSL-Anbindung besteht, haben wir eine Internet-Anbindung über einen privaten Netzbetreiber und verteilen "schnelles Internet aus der Steckdose" mittels Devolo-Technik im Haus, d. h. Adapter nutzen das hauseigene Stromnetz für die Internet-Verbindung.
Der PC ist als Drahtlos-LAN-Adapter WiFi mit einer festen IP-Adresse ohne DHCP eingerichtet.
Das Device ist über ein USB-Kabel angeschlossen, USB-Debugging ist aktiviert, und ich starte aus dem Android-Studio die App auf dem Handy.
Für das aktivierte WLAN auf dem Handy wird eine IP-Adresse angezeigt.
Im Netzwerk- und Freigabecenter des PC wird das Handy nicht aufgeführt.
Zusätzliche Ports habe ich nicht freigegeben, habe aber zum Test kurzzeitig die Firewall ausgeschaltet.
Kann es an diesen Einstellungen liegen, das es nicht klappt?

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.170

06.07.2016, 21:21:19 via App

Kannst du dir die Seite im Browser am Handy anzeigen lassen?
Wenn ja müste es eigentlich gehen.
Zudem empfehle ich eine HTTP Lib zu benutzen wie Ion Volley oder okHttp

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 2.902

06.07.2016, 21:21:44 via Website

Hallo Bärbel ,

im Groben kannst du so mit den Einstellungen arbeiten - das mache ich bei meinem Server/Client Programmierungen auch so.

Das Handy sollte aber ständig mit dem WLAN verbunden sein. und zwar mit dem gleichen Router in dem der PC eingebunden ist.
Bsp .
Hat der PC die IP 192.168.2.30, sollte das Handy auch in der gleichen IP-Range sein ( e.g. 192.168.2.xx)

Des weiteren brauchst du nicht die Firewall auszuschalten , sondern du solltest sie so einstellen , dass sie permanent den Port für eingehende und ausgehende Verbindung auf Port (TCP) 9933 zulässt. (auf alle Fälle eingehende Verbindungen)

Das Device versucht dann über WLAN über Port 9933 die Verbindung zum PC herzustellen - USB/ADB/AndroidStudio bleibt dabei ausser acht ..

Einfacher Test : USB Kabel raus , und versuche über den eingebauten Browser mal deine Web auf deinem PC zu erreichen , kommt da was ( egal was) und keine Fehlermeldung , hast du das Ganze schon mal Umgebungstechnisch zum Laufen gebracht .
http://192.168.2.30:9933/api/geraets/

Dann liegt auch der Fehler zu 100% an deinem Code.

Netzwerk / Freigabecenter spielt bei deinem Vorhaben keine Rolle

P.S ich würde serverseitig "Geraets" auf "geraets" ändern- hier ist schnell ein unnötiger typo produziert.

.
.
.
.

.

NACHTRAG : (Eben erst bewusst geworden)

Das wird auch wahrscheinlich dein trivialer Fehler sein, denn du hast Gross-Kleinschreibung deiner Webadresse unterschiedlich

Du schreibst im Text

"Im Internet Explorer erhalte ich beispielsweise bei Eingabe http://localhost:9933/api/Geraets/?id=1 eine Datei Geraets.json"

und im Quellcode rufst du

url = new URL("h ttp://" + LocalHost + ":9933/api/geraets/?" + contentXmlString);

auf

Stefan

— geändert am 06.07.2016, 23:37:00

Liebe Grüße - Stefan
[ App - Entwicklung ]

Antworten
  • Forum-Beiträge: 14

07.07.2016, 14:51:34 via Website

Vielen Dank für die Hinweise.
Geraets habe ich serverseitig auf geraets geändert. Leider hat es aber nichts gebracht.
Die IP meines Handys ist im gleichen Router wie der PC eingebunden und es ist ständig mit dem WLAN verbunden. Ich habe versucht, ohne USB-Kabel und bei ausgeschalteter Firewall über den eingebauten Google Chrome Browser des Handys eine Verbindung
h ttp://(IPv4)…:9933/api/geraets
aufzurufen. Da erhalte ich die jedoch die Meldung:
Bad Request - Invalid Hostname
HTTP Error 400.The request hostname is invalid.

Das gleiche kommt bei h ttp://(IPv4)…:9933/api/geraets/?id=1heraus.

Habt ihr eine Idee, woran das liegt?

Antworten
  • Forum-Beiträge: 2.902

07.07.2016, 15:01:31 via Website

.. Du hast ganz klar KEINE Verbindung zu deinem Server von aussen auf Port 9933.

Ich kenne leider nicht den WebServer du verwendest ( Obwohl ich beruflich mit VS arbeite)

Bei einem Standard Apache Server muss man in den Einstellungen angeben, ob man einen Zugriff von Außen ( ausser localhost) erlaubt.
Standardmäßig ist dies gesperrt - Vielleicht auch bei deinem Server.

Hierzu gebe ich auch das Ruder an die VS2015 Server-Spezies ab .

P.S ich denke , dass das Android-Forum jetzt auch bei diesem Stand der falsche Platz ist

— geändert am 07.07.2016, 17:32:03

Liebe Grüße - Stefan
[ App - Entwicklung ]

Bärbel R.

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.170

07.07.2016, 16:55:54 via Website

Naja ich weiß nciht wie der Server Konfiguriert ist, wenn du ihn aber nur in der Debug umgebung im VS laufen hast, mappt er die URL nur auf den Localhost und damit ist die seite von außen nichterreichbar.
Am besten du konfigurierst einf deinem rechner ein IIS und auf Port 80 und damit ists erledigt.

LG Pascal //It's not a bug, it's a feature. :) ;)

Bärbel R.

Antworten
  • Forum-Beiträge: 14

08.07.2016, 10:11:08 via Website

Hallo Stefan und Pascal,
vielen Dank für eure Hilfe, auch und obwohl das, wie ich jetzt sehe, wahrscheinlich in ein anderes Forum gehört.
Ich habe mich allein in die Aufgabe eingearbeitet und vorher noch nichts mit IIS und Client-Server-Tests zu tun gehabt. Da ich Windows 10 und damit das zugehörige IIS habe, habe ich unter
C:\Users...\Documents\IISExpress\config applicationhost.config, aspnet.config und redirection.config
C:\Users...\Documents\IISExpress\Logs*Projektname* Textdokumente der Form ex160707.log
C:\Users...\Documents\IISExpress\TraceLogFiles*Projektname* xml-Dokumente der Form fr000378.xml sowie freb.xsl
gefunden und dachte, es wäre alles ok.
Jetzt habe ich aber gesehen, dass in der Systemsteuerung bei Programme und Funktionen auf Windows-Funktionen ein- oder ausschalten Internetinformationsdienste nicht angehakt sind. Nun muss ich erst mal sehen, wie ich da richtig weitermachen kann.

Antworten

Empfohlene Artikel