Die Network Library erlaubt, über das TCP/IP Protokoll, mit anderen Gräten und Computern zu kommunizieren.
Die Network Library enthält zwei Objekte: Socket und ServerSocket.
Das Socket Objekt ist ein Kommunikation Endpunkt. Lesen und Schreiben werden mit Socket.InputStream und Socket.OutputStream durchgeführt.
Das Englische OriginalTutorial.
ServerSocket ist ein Objekt, das eingehende Verbindungen abhört. Sobald eine Verbindung aufgebaut ist wird ein Event ausgelöst in dem ein Socket Objekt übergeben wird. Dieses Socket Objekt dient zur Behandlung des neuen Kundens.
Benutzung als Kunde
Benötigte Schritte:
- Ein Socket Objekt erstellen und initialisieren.
- Socket.Connect aufrufen. mit der Server-Adresse.
- Die Verbindung wird im Hintergrund durchgeführt. Ein Connected Event wird ausgelöst wenn die Verbindung aufgebaut ist oder wenn sie fehlgegangen ist.
- Mit der anderen Maschine kommunizieren, mit Socket.InputStream die Daten lesen und mit Socket.OutputStream die Daten schreiben.
Benutzung als Server
Benötigte Schritte:
- Ein ServerSocket Objekt erstellen und initialisieren.
- ServerSocket.Listen aufrufen zum Abhören auf einkommende Verbindungen. Dies geschieht im Hintergrund.
- Sobald die Verbindung aufgebaut ist wird ein NewConnection Event ausgelöst das ein Socket Objekt übergibt.
- ServerSocket.Listen aufrufen wenn man mehr Verbindungen erlauben will.
- Mit dem Kunden kommunizieren, mit dem übergebenen Socket Objekt.
Wir werden zwei Beispiele erklären.
Das erste Beispiel verbindet mit einem Zeitserver und zeigt das aktuelle Datum und die aktuelle Zeit an, die vom Server erhalten wurden.
Wir erstellen ein Socket Objekt und Versuchen mit dem Server, über die Schnittstelle (port) 13, in Verbindung zu kommen.
Der nächste Schritt ist auf das Connected Event zu warten.
Wenn die Verbindung erfolgreich ist, erstellen wir ein TextReader Objekt und initialisieren es mit Socket1.InputStream. In diesem Fall wollen wir Buchstaben lesen und keine Bytes, deshalb verwenden wir ein TextReader Objekt.
Ein Aufruf von tr.ReadLine könnte blockieren. Aber wir wollen ja mindestens nur eine Zeile lesen, also geht es. Dann lesen wir alle andere verfügbare Zeilen (tr.Ready heißt daß Daten im Buffer (Puffer) zur Verfügung stehen).
In der zweiten Anwendung werden wir eine Dateiübertragung erstellen die Dateien vom Computer auf des Gerät kopiert.
Das Gerät wird ein ServerSocket Objekt benutzen um auf eingehende Verbindungen zu hören.
Sobald eine Verbindung aufgebaut ist, aktivieren wir einen Timer der alle 200ms überprüft ob lesbare Daten zur Verfügung stehen (siehe Anmerkung am Ende des Tutorials).
Die Datei wird mit einem spezifischen Protokoll gesandt. Zuerst wird der Dateiname gesandt und dann die eigentlichen Dateidaten. Wir benutzen ein RandomAccessFile Objekt um die gelesenen Bytes in Zahlen umzuwandeln. RandomAccessFile kann nur mit Dateien oder Bytearrays arbeiten, wir benutzen die zweite Möglichkeit.
RandomAccessFile wird für 'little endian byte order' (Klein-Ender Bytereihenfolge) konfiguriert. Das ist hier wichtig da der Desktop auch diese Reihenfolge benutzt.
Das Desktop Beispielprogramm wurde mit Basic4PPC geschrieben.
Sobald eine Verbindung aufgebaut ist muß der Benutzer eine Datei wählen und diese wird dann an das Gerät gesandt welches die Datei unter /sccard/android speichert.
Beide Anwendungen sind angehängt.
Einige Kommentare über den Code:
- Der Server hört die Schnittstelle (port) 2222 ab.
Wenn der Server startet, zeigt er seine IP-Adresse an (IP Intenet Protokoll). Der Desktop-Kunde muß diese Adresse verwenden um die Verbindung mit einem echten Gerät aufzubauen (diese IP-Adresse funktioniert nicht mit dem Emulator).
Wenn man aber doch mit dem Emulator arbeiten will, oder mit dem Gerät wenn es im Debugmodus mit dem Computer verbunden ist, kann man 'adb' benutzen um dem Gerät eine 'desktop localhost port' zu übertragen.
Das wird mit "adb forward tcp:5007 tcp:2222" gemacht.
Jetzt müssen wir im Kundencode (client code) die Verbindung mit dem localhost IP Port 5007 erstellen.
Noch einmal, wenn man diese Anwendung mit dem Emulator testen will muß man zuerst diesen adb Befehl durchführen. Adb ist Teil des Android SDKs.
- Auf Verbindungen zu hören:
In Sub Activity_Resume (das direkt nach Activity_Create aufgerufen wird) rufen wir ServerSocket.Listen auf und starten das Abhören für Verbindungen. Beachten Sie daß man diese Methode mehrere male, ohne Risiko, aufrufen kann.
In Sub Activity_Pause schließen wir die aktive Verbindung (falls eine existiert) und stoppen auch das Abhören. Dies erfolgt nur wenn der Benutzer auf die 'Back' Taste drückt (UserClosed = True).
Das ServerSocket Objekt wird dann später in Activity_Create initialisiert.
Die Anwendung auf der Serverseite kann neue Verbindungen verwalten. Sie ersetzt einfach die vorhergehende Verbindung durch die Neue.
Die Desktop Kunden Beispielanwendung verwaltet keine unterbrochene Verbindungen. Diese müssen Sie wieder neu starten für eine neue Verbindung.
Edit: Es ist empfohlen das neue AsnycStreams Objekt zu benutzen anstatt die verfügbaren Bytes mit einem Timer abzufragen. AsyncStreams ist einfacher und hauptsächlich sicherer.
Beispielprogramme:
NetworkExample.zip
Die Network Library enthält zwei Objekte: Socket und ServerSocket.
Das Socket Objekt ist ein Kommunikation Endpunkt. Lesen und Schreiben werden mit Socket.InputStream und Socket.OutputStream durchgeführt.
Das Englische OriginalTutorial.
ServerSocket ist ein Objekt, das eingehende Verbindungen abhört. Sobald eine Verbindung aufgebaut ist wird ein Event ausgelöst in dem ein Socket Objekt übergeben wird. Dieses Socket Objekt dient zur Behandlung des neuen Kundens.
Benutzung als Kunde
Benötigte Schritte:
- Ein Socket Objekt erstellen und initialisieren.
- Socket.Connect aufrufen. mit der Server-Adresse.
- Die Verbindung wird im Hintergrund durchgeführt. Ein Connected Event wird ausgelöst wenn die Verbindung aufgebaut ist oder wenn sie fehlgegangen ist.
- Mit der anderen Maschine kommunizieren, mit Socket.InputStream die Daten lesen und mit Socket.OutputStream die Daten schreiben.
Benutzung als Server
Benötigte Schritte:
- Ein ServerSocket Objekt erstellen und initialisieren.
- ServerSocket.Listen aufrufen zum Abhören auf einkommende Verbindungen. Dies geschieht im Hintergrund.
- Sobald die Verbindung aufgebaut ist wird ein NewConnection Event ausgelöst das ein Socket Objekt übergibt.
- ServerSocket.Listen aufrufen wenn man mehr Verbindungen erlauben will.
- Mit dem Kunden kommunizieren, mit dem übergebenen Socket Objekt.
Wir werden zwei Beispiele erklären.
Das erste Beispiel verbindet mit einem Zeitserver und zeigt das aktuelle Datum und die aktuelle Zeit an, die vom Server erhalten wurden.
B4X:
Sub Process_Globals
Dim Socket1 As Socket
End Sub
Sub Globals
End Sub
Sub Activity_Create(FirstTime As Boolean)
Socket1.Initialize("Socket1")
Socket1.Connect("nist1-ny.ustiming.org" , 13, 20000)
End Sub
Sub Socket1_Connected (Successful As Boolean)
If Successful = False Then
Msgbox(LastException.Message, "Error connecting")
Return
End If
Dim tr As TextReader
tr.Initialize(Socket1.InputStream)
Dim sb As StringBuilder
sb.Initialize
sb.Append(tr.ReadLine) 'read at least one line
Do While tr.Ready
sb.Append(CRLF).Append(tr.ReadLine)
Loop
Msgbox("Time received: " & CRLF & sb.ToString, "")
Socket1.Close
End Sub
Der nächste Schritt ist auf das Connected Event zu warten.
Wenn die Verbindung erfolgreich ist, erstellen wir ein TextReader Objekt und initialisieren es mit Socket1.InputStream. In diesem Fall wollen wir Buchstaben lesen und keine Bytes, deshalb verwenden wir ein TextReader Objekt.
Ein Aufruf von tr.ReadLine könnte blockieren. Aber wir wollen ja mindestens nur eine Zeile lesen, also geht es. Dann lesen wir alle andere verfügbare Zeilen (tr.Ready heißt daß Daten im Buffer (Puffer) zur Verfügung stehen).
In der zweiten Anwendung werden wir eine Dateiübertragung erstellen die Dateien vom Computer auf des Gerät kopiert.
Das Gerät wird ein ServerSocket Objekt benutzen um auf eingehende Verbindungen zu hören.
Sobald eine Verbindung aufgebaut ist, aktivieren wir einen Timer der alle 200ms überprüft ob lesbare Daten zur Verfügung stehen (siehe Anmerkung am Ende des Tutorials).
Die Datei wird mit einem spezifischen Protokoll gesandt. Zuerst wird der Dateiname gesandt und dann die eigentlichen Dateidaten. Wir benutzen ein RandomAccessFile Objekt um die gelesenen Bytes in Zahlen umzuwandeln. RandomAccessFile kann nur mit Dateien oder Bytearrays arbeiten, wir benutzen die zweite Möglichkeit.
RandomAccessFile wird für 'little endian byte order' (Klein-Ender Bytereihenfolge) konfiguriert. Das ist hier wichtig da der Desktop auch diese Reihenfolge benutzt.
Das Desktop Beispielprogramm wurde mit Basic4PPC geschrieben.
Sobald eine Verbindung aufgebaut ist muß der Benutzer eine Datei wählen und diese wird dann an das Gerät gesandt welches die Datei unter /sccard/android speichert.
Beide Anwendungen sind angehängt.
Einige Kommentare über den Code:
- Der Server hört die Schnittstelle (port) 2222 ab.
Wenn der Server startet, zeigt er seine IP-Adresse an (IP Intenet Protokoll). Der Desktop-Kunde muß diese Adresse verwenden um die Verbindung mit einem echten Gerät aufzubauen (diese IP-Adresse funktioniert nicht mit dem Emulator).
Wenn man aber doch mit dem Emulator arbeiten will, oder mit dem Gerät wenn es im Debugmodus mit dem Computer verbunden ist, kann man 'adb' benutzen um dem Gerät eine 'desktop localhost port' zu übertragen.
Das wird mit "adb forward tcp:5007 tcp:2222" gemacht.
Jetzt müssen wir im Kundencode (client code) die Verbindung mit dem localhost IP Port 5007 erstellen.
B4X:
Client.Connect("127.0.0.1", 5007)
- Auf Verbindungen zu hören:
B4X:
Sub Activity_Resume
ServerSocket1.Listen
End Sub
Sub Activity_Pause (UserClosed As Boolean)
If UserClosed Then
Timer1.Enabled = False
Socket1.Close
ServerSocket1.Close 'stop listening
End If
End Sub
Sub ServerSocket1_NewConnection (Successful As Boolean, NewSocket As Socket)
If Successful Then
Socket1 = NewSocket
Timer1.Enabled = True
InputStream1 = Socket1.InputStream
OutputStream1 = Socket1.OutputStream
ToastMessageShow("Connected", True)
Else
Msgbox(LastException.Message, "Error connecting")
End If
ServerSocket1.Listen 'Continue listening to new incoming connections
End Sub
In Sub Activity_Pause schließen wir die aktive Verbindung (falls eine existiert) und stoppen auch das Abhören. Dies erfolgt nur wenn der Benutzer auf die 'Back' Taste drückt (UserClosed = True).
Das ServerSocket Objekt wird dann später in Activity_Create initialisiert.
Die Anwendung auf der Serverseite kann neue Verbindungen verwalten. Sie ersetzt einfach die vorhergehende Verbindung durch die Neue.
Die Desktop Kunden Beispielanwendung verwaltet keine unterbrochene Verbindungen. Diese müssen Sie wieder neu starten für eine neue Verbindung.
Edit: Es ist empfohlen das neue AsnycStreams Objekt zu benutzen anstatt die verfügbaren Bytes mit einem Timer abzufragen. AsyncStreams ist einfacher und hauptsächlich sicherer.
Beispielprogramme: