Version | Anpassungen |
---|---|
1 (2018-01-27) | Initiale Version |
2 (2018-12-08) | Seit Dezember 2018 gab es Probleme mit Netzwerkzugriffen. Diese Zugriffe müssen nun in
separaten Threads ausgeführt werden. Die Komponente wurde entsprechend umgeschrieben. Zusätzlich wurde die Eigenschaft InitErr eingeführt, über die Fehler bei der Initialisierung der Komponente abgerufen werden können. |
3 (2019-01-11) | Leider hatte die Version 2 ein paar Probleme. Die Version 3 ist neu strukturiert. Sie ist
leider nicht kompatibel mit der vorhergehenden Version. Zum Update deshalb
die unten aufgeführten Migrationshinweise beachten. Die alte Version 2 ist hier archiviert. |
3.1 (2019-04-29) | Die neue Eigenschaft BinaryMode erlaubt das Übertragen von binären Daten. Diese Version ist kompatibel mit der Version 3.0. Beim Hochladen bleiben die bestehenden Verknüpfungen der Blöcke erhalten. |
3.2 (2020-02-17) | - DropSentToYourself wurde nach Start des Listeners nicht
weitergereicht. - Die Bestimmung der Local-Host-IP per Enumration über die Netzwerkinterfaces führt zu Problemen bei Endgeräten, die mehr als ein Interface besitzen. DropSentToYourself hat nicht funktioniert. DropSentToYourself vergleicht nun die Absender-Adresse mit allen vorhandenen NIC-Adressen. LocalHost ist nun die Adresse, mit der das Internet erreicht wird (google.com, 8.8.8.8). |
4.0 (2020-07-15) | Die bestehende Version war überaus "buggy", also mit vielen Fehlern behaftet. Es war halt
eine der ersten Extensions, die ich geschrieben hatte. Ich habe das Projekt deshalb noch einmal
komplett neu aufgesetzt. Der Vorteil: Die Bugs sind raus und es gibt erweiterte Methoden, die
das Zusammenstellen der Blöcke im App Inventor vereinfachen. Der Nachteil ist, die Version
ist nicht kompatibel zur alten. Die alte Version ist hier archiviert. |
4.1 (2021-01-15) | Fehler bei DropSentToYourself behoben. |
4.2 (2021-03-30) | - Problem bei der Benutzung der selben Port-Nummer beim Senden und Empfangen behoben. - Absturz des Listeners im Companion nach "Refresh Companion Screen" behoben. |
4.3 (2021-04-09) | Senden und Empfangen eines ByteArray hinzügefügt. |
4.4 (2022-03-31) | Multicast-Option hinzugefügt. |
Für ein Projekt sollte eine Android-App entwickelt werden, die mit einem ESP8266(-Projekt) kommuniziert. Zur App-Entwicklung sollte wegen der einfachen Handhabung der MIT App Inventor 2 benutzt werden.
Die IP-Adressen der verfügbaren ESP8266-Geräte sollten im Projekt nicht fest vorgegeben werden. Die App soll selbst ermitteln, welche Geräte gerade aktiv sind und unter welchen Adressen sie angesprochen werden können.
Zur Erledigung dieser Aufgabe (Name Service) bietet sich die Nutzung der Broadcast-Funktion von UDP an. Man sendet einfach an einen vorher vereinbarten Port ein Broadcast-Datagramm an alle im lokalen Netzwerk vorhandenen Geräte mit der Aufforderung, die eigenen Verbindungsdaten zurück zu liefern. Die Geräte, die auf dem vereinbarten Port lauschen, senden daraufhin ihre IP und ggf. weitere Daten an den Absender zurück. Der Absender sammelt die Antworten auf und kennt damit alle aktiven Geräte. Da die Paket-Übermittlung bei UDP nicht garantiert ist, empfiehlt es sich, diesen Vorgang zu wiederholen und die Vereinigungsmenge der Antworten zu nutzen.
Um gezielt die Geräte eines Projekts ansprechen zu können, vereinbart man entweder unterschiedliche Ports oder eine Geräte-Kennung.
Nun kommt die Krux. Der App Inventor hat kein eingebautes UDP und ich habe auch keine funktionierende Erweiterung (Extension) gefunden. Also selber machen.
Hinweis:
Die Extension klappt einwandfrei, wenn sich Smartphone und Gegenstation im gleichen (lokalen) Netzwerk befinden. Ist das Smartphone nur per Mobilfunknetz verbunden, ist es i.d.R. nicht erreichbar. Der Grund ist, dass das Smartphone nicht direkt mit dem Internet verbunden ist, sondern nur mit dem lokalen Netzwerk des Mobilfunkanbieters.
Ein Gerät im eigenen LAN kann man von außerhalb per Port-Weiterleitung (port porwarding) am eigenen Router erreichen (ggf. via DDNS). Den Router des Providers wird man nicht beeinflussen können. Also senden vom Smartphone an ein Gerät im LAN funktioniert, umgekehrt geht es nicht.
Das gleiche gilt übrigens auch für TCP. Wenn das Smartphone nur mit dem Mobilfunknetz verbunden ist, kann die Verbindung kann nur vom Smartphone aus aufgebaut werden. Das Gerät im LAN muss als Server agieren, wartet also auf eine eingehende Verbindungsanforderung. Das Smartphone agiert als Client, initiiert den Verbindungsaufbau. Ist die Verbindung einmal eingerichtet, haben sich die Router intern über Adressen und Ports abgestimmt. Der Datentransfer ist dann in beide Richtungen möglich.
Hinweis:
Auf UNIX-Systemen sind die Port-Nummern bis 1023 (einschl.) dem System vorbehalten. Diese Einschränkungen wurden bei LINUX und damit auch bei Android beibehalten. Um diese Port-Nummern benutzen zu können benötigt man Root-Berechtigungen. Ähnliches gilt für Apples iOS.
Diese Extensionen kann deshalb nicht mit Port-Nummern unterhalb von 1024 betrieben werden.
Damit es nicht übersehen wird:
Manche Geräte, die per UDP angesteuert werden, geben dem Absender eine Antwort auf der Adresse, mit der gesendet wird. Damit diese Empfangen werden kann, muss die Sende- und Empfangsadresse der App übereinstimmen. Der Parameter LocalPort (= Port auf dem gesendet wird) darf nicht die Voreinstellung 0 behalten, sondern muss entsprechend gesetzt werden.
Inhaltsverzeichnis
Senden an eine Multicast-Gruppe
Empfangen von Multicast-Paketen
Texte versenden und empfangen (URSAI2UDPTest)
Das ZIP-Archiv UrsAI2UDP zum Download. Das Archiv enthält den Quellcode, das kompilierte Binary zum Upload in den App Inventor und eine Beispiel-Anwendung.
Die Extension enthält zwei Komponenten. Wenn sie in ein App Inventor Projekt importiert wird, erscheinen unter der Rubrik "Extension" zwei Einträge.
UDPListener ist eine Komponente die auf eingehende Datagramme lauscht und diese dem Projekt zur Verfügung stellt. UDPXmitter dient zum Versenden von Datagrammen.
Einige tiefer gehende Informationen zu UDP findet man auf meiner Seite .NET UdpClient: Aufs Bit geschaut. Insbesondere die Abschnitte über Adressierungsschemata und die Java-Schnittstelle sind auch für Android von Relevanz.
Bei technischen Anwendungen oder bei der Ansteuerung von Geräten ist es häufig notwendig, mit Binärdaten zu arbeiten. Mit der Version 4.3 wurde das Senden und Empfangen von Binärdaten über die UrsAI2ByteArray-Extension deutlich vereinfacht (siehe auch Beispiel UDPBinaryTest).
Zum Versenden von Datagrammen wurden vier unterschiedliche Methoden implementiert. Sie sollen die Größe und Anzahl der notwendigen Programm-Blöcke im App Inventor reduzieren. Viele und große Blöcke machen ein AI2-Projekt schnell unübersichtlich.
Häufig ist die Ziel-Adresse immer die gleiche. Im Designer kann für diese Fälle die Ziel-Adressdaten (RemoteHost, RemotePort) hinterlegt werden. Xmit und XmitAsync senden dann die im Designer hinterlegten Adressen. Die Blöcke werden dadurch klein gehalten. Es ist praktisch nur eine "Zeile" notwendig.
XmitTo und XmitToAsync erlauben eine eigenständige Angabe der Ziel-Adresse.
Weiterhin unterscheiden sich die Methoden in der Art der Fehlerbehandlung. Die mit der Endung "...Async" quittieren den Versand einer Nachricht mit den Ereignissen AfterXmit und XmitFailure. AfterXmit wird nach jedem Versand ausgelöst. Wer nur an Fehlersituationen interessiert ist, verwendet das Ereignis XmitFailure, das im Fehlerfall zusätzlich ausgelöst wird. Die beiden anderen Methoden liefern die Fehlercodes als Rückgabewert.
In der Regel ist es nicht erforderlich festzulegen, von welchem lokalen Port aus Datagramme versandt werden. Sollte dies in speziellen Fällen doch einmal notwendig sein, kann die lokale Port-Nummer (LocalPort) im Designer festgelegt werden. Ist der Wert "0" (der Vorschlagswert), sucht sich das System einen freien Port zum Versenden aus.
Selbstverständlich können alle Designer-Properties per Block überschrieben werden.
Zum Versand einer Nachricht sind drei Angaben notwendig: Ziel-Adresse, Absender-Adresse und die Nachricht selbst. Netzadressen bestehen aus zwei Komponenten: IP(-Adresse) und Port(-Nummer). Der Port wird meist mit einem gewissen Dienst verbunden (s. auch Wikipedia: Standardisierte Ports).
Diese Extension berücksichtigt nur IPv4-Adressen. Sie ist eine Kombination vier Zahlen, jeweils im Bereich 0..255. Eine vollständige Netzwerkadresse wird so angegeben "IP:Port", z.B. "192.168.178.35:2003".
Einige Adressen haben besondere Bedeutungen. Zu UDP-Adress-Schemata siehe UdpClient: Aufs Bit geschaut / Adressierungsschemata. Zu Endpunkten in Java UdpClient: Aufs Bit geschaut / Java
Die Geräte, die im Netzwerk miteinander kommunizieren werden als "Endpunkt" oder "Host" bezeichnet (es ist nicht genau das selbe, die Begriffe werden jedoch häufig gleichwertig benutzt). Es gibt also den Absender, der mit "local host" bezeichnet wird und den Empfänger, der "remote host" genannt wird.
Um die Absender-Adresse braucht man sich im Regelfall nicht zu kümmern. Macht man keine Angaben, verwendet die Extension die Adresse "0.0.0.0:0". Diese Adresse bewirkt, dass sich das System (genauer der "Dienstanbieter", also die Netzwerk-Firmware) sich ein Netzwerk-Interface aussuchen kann, mit dem es die Ziel-Adresse erreichen kann. Dabei sucht es sich einen beliebigen freien Port aus.
Will man in speziellen Fällen die Absender-Adresse näher spezifizieren, kann man dies über die Eigenschaft LocalPort vornehmen. Ein Android-Device hat zu einer Zeit i.d.R. nur ein aktives Netzwerk-Interface. Dies ist entweder die mobile Datenverbindung oder das WLAN. Deshalb wurde eine Auswahl des lokalen Netzwerk-Interfaces nicht implementiert.
Die Ziel-Adresse muss auf jeden Fall angegeben werden. Dies geschieht entweder über die Designer-Eigenschaften RemoteHost und RemotePort oder als Angabe bei der Xmit...-Methode.
Bei RemoteHost kann entweder eine IP-Adresse oder der Name des Empfängers angegeben werden (z.B. "www.google.de"). Die Extension versucht dann, die zugehörige IP zu ermitteln. Für die Designer-Eigenschaft RemoteHost wird das Resultat der Ermittlung in der Eigenschaft RemoteIP ausgewiesen. Konnte die IP nicht ermittelt werden, ist RemoteIP leer. Ein Versand an diesen Host ist dann nicht möglich (wird zum Fehler UnknownRemoteHost (Code 1) führen).
Da sich IP-Adressen nur sehr selten ändern, wird die zu einem Host-Namen gehörende IP nur beim Festlegen des Namens ermittelt. Tritt unerwartet der Fehler UnknownRemoteHost (Code 1) auf, kann man versuchen, die Eigenschaft RemoteHost neu festzulegen. Die zugehörige IP-Adresse wird dann neu ermittelt.
Im AI2-Umfeld bestehen Nachrichten im Regelfall aus Texten. Nicht-Text-Angaben werden in Texte gewandelt:
Zahlen werden
in Texte umgewandelt. Der Empfänger erhält die vier Ziffernzeichen "1234".
Listen werden im
JSON-Format
übertragen. Der Empfänger erhält die Zeichenfolge [1234, "Ulli"].
Manche Empfänger benötigen jedoch bestimmte Byte-Folgen, z.B. das Byte 123 (Hex 7B) und nicht die Zeichenfolge "123". Ist der Binärmodus eingeschaltet, wird die Nachricht als kommaseparierte Folge von Byte-Angabe interpretiert und die Nachricht als Byte-Folge versandt (Details s.u. Binärdaten).
Zum Senden von Byte-Arrays wird die Extension UrsAI2ByteArray benötigt. Mit ihr können Binärsequenzen komfortabel verwaltet werden. Das Versenden der Byte-Arrays erfolgt über die Methoden XmitByteArray..., jeweils mit Angabe einer UrsAI2ByteArray Komponente. Z.B.:
XmitData ist eine Instanz der UrsAI2ByteArray-Extension. Dies ist der letzte Eintrag in der Block-Übersicht:
Das Senden an eine Multicast-Gruppe unterscheidet sich nicht vom "normalen" Senden. Als RemoteHost muss die IP-Adresse der Gruppe angegeben werden.
Block | Funktion | Anmerkung |
---|---|---|
Eigenschaften | ||
Legt die Port-Nummer fest, die zum senden einer Nachricht verwandt werden soll. | Ist der Wert 0 oder negativ, ermittelt das Android-Betriebssystem einen freien Port. 0 ist der empfohlene Standardwert. Das Betriebssystem sucht sich dann selbst einen freien Port zum Versenden aus. Gültige Werte sind 0...65535. Diese Angabe wirkt sich auf alle Xmit...-Methoden einer Instanz der Extension aus. |
|
Legt die (Standard-) Ziel-Adresse fest. | Es kann eine IP-Adresse oder der Name angegeben werden. Diese Adresse wird von den Methoden Xmit und XmitAsync verwendet. |
|
Liefert die IP-Adresse, die zur Designer-Eigenschaft RemoteHost gehört. | Konnte die IP-Adresse nicht ermittelt werden, wird eine leere Zeichenfolge zurück geliefert.
Das Versenden eines Datagramms schlägt dann fehl ( Fehler UnknownRemoteHost (Code 1). |
|
Legt die (Standard-) Ziel-Port-Nummer fest. | Dieser Port wird von den Methoden Xmit und
XmitAsync verwendet. Gültige Werte sind 1...65535. Man sollte jedoch keine Portnummern verwenden, die kleiner als 1024 sind. Viele dieser Nummern sind für spezielle Zwecke reserviert. Die Benutzung kann je nach Netzwerkkonfiguration zu Problemen führen. |
|
Legt fest, ob die beim Senden übergebene Nachricht in eine Byte-Array konvertiert werden soll. | Details zum Binär-Modus s.u. Binärdaten. | |
Liefert die Liste der IP-Adresse aller Netzwerk-Interfaces. | In der Regel enthält diese Liste nur einen Eintrag, der mit der Angabe in LocalHost übereinstimmt. | |
Liefert die IP-Adresse des Standard-Netzwerk-Interfaces. | Kann keine Verbindung zum Internet hergestellt werden, wird eine leere Zeichenfolge zurück
geliefert. Konkret wird versucht die Internet-Adresse "8.8.8.8" (Googles öffentlicher DNS-Server) zu erreichen. Das Android-Betriebssystem wählt hierzu ein passendes Netzwerk-Interface aus. |
|
Angaben zum zuletzt aufgetretenen Fehler. LastAction: Bezeichnung der Methode, die zuletzt ausgeführt wurde. LastErrorCode: Fehler-Code LastErrorMessage: Fehlerbezeichnung im (englischen) Klartext. |
Ist bei der zuletzt ausgeführten Aktion kein Fehler aufgetreten, hat LastErrorCode den Wert 0 und LastErrorMessage liefert eine leere Zeichenfolge. | |
Methoden | ||
Sendet die Nachricht an die über RemoteHost und
RemotePort hinterlegte Ziel-Adresse. Rückgabewert ist der Fehler-Code. |
||
Sendet die Nachricht an die angegebene Ziel-Adresse. Rückgabewert ist der Fehler-Code. |
||
Sendet die Nachricht an die über RemoteHost und
RemotePort hinterlegte Ziel-Adresse. Der Erfolg der Übertragung wird über die Ereignisse AfterXmit und XmitFailure mitgeteilt. |
siehe auch oben RemoteHost und RemoteIP. | |
Sendet die Nachricht an die abgegebene Ziel-Adresse. Der Erfolg der Übertragung wird über die Ereignisse AfterXmit und XmitFailure mitgeteilt. |
siehe auch oben RemoteHost und RemoteIP. | |
Sendet ein ByteArray an die über
RemoteHost und RemotePort
hinterlegte Ziel-Adresse. Rückgabewert ist der Fehler-Code. |
||
Sendet ein ByteArray an die angegebene
Ziel-Adresse. Rückgabewert ist der Fehler-Code. |
||
Sendet ein ByteArray an die über
RemoteHost und RemotePort
hinterlegte Ziel-Adresse. Der Erfolg der Übertragung wird über die Ereignisse AfterXmit und XmitFailure mitgeteilt. |
siehe auch oben RemoteHost und RemoteIP. | |
Sendet ein ByteArray an die abgegebene
Ziel-Adresse. Der Erfolg der Übertragung wird über die Ereignisse AfterXmit und XmitFailure mitgeteilt. |
siehe auch oben RemoteHost und RemoteIP. | |
Ereignisse | ||
Teilt das Ergebnis der Übertragung mit den asynchronen Methoden mit. Success: true, wenn die Übertragung erfolgreich war, andernfalls false. ErrorCode: Fehler-Code. |
Das Ereignis wird nach jeder Übertragung mit den Methoden XmitAsync oder XmitToAsync ausgelöst. | |
XmitFailure wird bei einem Fehler bei der Übertragung
mit den asynchronen Methoden zusätzlich zum Ereignis
AfterXmit ausgelöst. ErrorCode: Fehler-Code. |
Wer nur an Fehlern interessiert ist, erspart sich die Abfrage von Success im Ereignis AfterXmit. |
Code | Meldung | Bedeutung |
---|---|---|
0 | Versand erfolgreich. | |
1 | Unknown Remote Host | Die IP-Adresse des Empfängers ist ungültig oder konnte nicht ermittelt werden. |
2 | Invalid Local Port | Die Angabe zu LocalPort ist ungültig oder der Port ist belegt. |
3 | Invalid Remote Port | Die Angabe zu RemotePort ist ungültig. |
4 | Xmit failed | Fehler bei der Übertragung. |
5 | Binary conversion failed | Die angegebene Zeichenfolge konnte nicht in ein Byte-Array konvertiert werden. |
8 | Invalid Data Type | Die übergebene Komponente ist nicht vom Typ UrsAI2ByteArray. |
Der Empfang der Datagramme erfolgt über die Komponente UDPListener. Nach dem Start überprüft diese Komponente in einer nebenläufigen Endlosschleife, ob Datagramm-Pakete eingetroffen sind. Ist dies der Fall wird der Applikation der Empfang über das Ereignis DataReceived mitgeteilt.
Die UDPListener-Komponente besitzt nur die beiden Methoden Start und Stop, die den Empfang von UDP-Datagrammen starten bzw. beenden. Dazu gibt es zwei Ereignisse: DataReceived wird ausgelöst, wenn ein Datagramm empfangen wurde, ListenerFailure zeigt an, dass die Empfangsschleife auf Grund eines Fehlers abgebrochen wurde. Über die Eigenschaft isRunning kann jederzeit abgefragt werden, ob die Empfangsschleife aktiv ist.
UDP erlaubt es, Broadcast-Nachrichten zu versenden. Dabei entsteht das Problem, dass auch von der App selbst gesendete Datagramme empfangen werden. Über die Eigenschaft DropSentToYourself werden Datagramme heraus gefiltert, deren Absender die eigene IP-Adresse ist. Wenn UPD zur Interprozesskommunikation verwandt wird, wird diese dabei auch unterbunden.
Das Öffnen eines zweiten Screens unterbricht den Nachrichtenempfang nicht! Der erste Screen erhält weiterhin die Ereignisse DataReceived und ListenerFailure. Die mit dem Ereignis verbundenen Blöcke werden weiterhin ausgeführt. Soll dies nicht geschehen, muss der Listener vor dem Öffnen des zweiten Screens gestoppt und nach der Rückkehr wieder gestartet werden.
Ebenfalls blockiert ein laufender Listener den zugehörigen Port. Im zweiten Screen kann auf diesem Port kein weiterer Listener gestartet werden. Sollen Datagramme auf dem gleichen Port wie im ersten Screen empfangen werden, muss der Listener des ersten Screens vor dem Öffnen des zweiten Screens gestoppt und im zweiten Screen wieder geöffnet werden.
Die Extension räumt auf, d.h. stoppt einen laufenden Listener, wenn ein Screen geschlossen wird. Es bleiben also letztendlich keine laufenden Listener übrig. Dieses Aufräumen erfolgt aber verzögert im Hintergrund. Das Ereignis OtherScreenClosed tritt deshalb ein, bevor der Listener intern gestoppt und der Port wieder freigegeben wurde. Wenn nach der Rückkehr aus dem zweiten Screen der Listener im ersten Screen auf dem gleichen Port wie im zweiten wieder im Ereignis OtherScreenClosed gestartet werden soll -was sich anbietet-
muss der Listener im zweiten Screen vor dem Schließen des Screens definitiv wieder gestoppt werden.
Wichtig ist, dass im zweiten Screen das Ereignis BackPressed abgefangen wird:
Im AI2-Umfeld bestehen Nachrichten im Regelfall aus Texten. In manchen Fällen besteht das Datagramm aber aus einer Folge von beliebigen Bytes (Byte-Array). Schalten man den Binärmodus ein, werden die empfangenen Bytes nicht direkt in Texte umgewandelt, sondern es werden die einzelnen Bytes als über Semikolons separierte Dezimalzahlen ausgegeben.
Erhält der Listener ein Datagramm mit dem Inhalt (hexadezimal) 48 61 6C 6C 6F, würde dieses normalerweise in den Test "Hallo" übersetzt werden. Bei eingeschaltetem Binärmodus wird "72;97;108;108;111" ausgegeben (Details s.u. Binärdaten).
Zum Empfangen von Byte-Arrays muss der Eigenschaft ReceivingByteArray eine Instanz der UrsAI2ByteArray-Extension zugewiesen werden. Dies kann im Designer oder per Anweisungsblock geschehen.
RcvData ist eine Instanz der UrsAI2ByteArray-Extension. Dies ist der letzte Eintrag in der Block-Übersicht:
Wenn ein UDP-Datenpaket (Datagramm) eintrifft, werden die empfangenen Daten zusätzlich in die spezifizierte UrsAI2ByteArray-Instanz kopiert. Danach wird das Ereignis DataReceived ausgelöst. Die Daten stehen in der UrsAI2ByteArray Komponente nur so lange zur Verfügung, wie sich die Code-Ausführung im Ereignis DataReceived befindet. Wird die Ereignismethode verlassen, können die Daten durch weitere empfangene Pakete überschrieben werden.
Für das Empfangen von Multicast-Paketen steht die Methode StartMulticast zur Verfügung. Die Extension tritt automatisch der angegebenen Mullticast-Gruppe bei.
Block | Funktion | Anmerkung |
---|---|---|
Eigenschaften | ||
Legt fest, ob die empfangene Nachricht als Byte-Array interpretiert werden soll. | Das empfangene Paket wird in einen String mit einer Folge von Dezimalzahlen übersetzt. Details zum Binär-Modus s.u. Binärdaten |
|
Die Eigenschaft DropSentToYourself steuert das Verhalten beim Empfang Broadcast-Datagrammen. Der Block ist standardmäßig so eingestellt, dass Nachrichten ignoriert werden, die von der eigenen IP versandt wurden. Sollen diese dennoch empfangen werden, ist DropSentToYourself auf false zu setzen. | Die Voreinstellung ist true. | |
Legt die UrsAI2ByteArray Komponente fest, in der die empfangenen Daten binär zur Verfügung stehen sollen. | Die Daten stehen in der UrsAI2ByteArray Komponente nur so lange zur Verfügung, wie sich die Code-Ausführung im Ereignis DataReceived befindet. Wird die Ereignismethode verlassen, können die Daten durch weitere empfangene Pakete überschrieben werden. | |
Entfernt die UrsAI2ByteArray Komponente. | ||
Über die Eigenschaft isRunning kann abgefragt werden, ob der Listener aktuell aktiv ist. | ||
Liefert die Liste der IP-Adresse aller Netzwerk-Interfaces. | In der Regel enthält diese Liste nur einen Eintrag, der mit der Angabe in LocalHost übereinstimmt. | |
Liefert die IP-Adresse des Standard-Netzwerk-Interfaces. | Kann keine Verbindung zum Internet hergestellt werden, wird eine leere Zeichenfolge zurück
geliefert. Konkret wird versucht die Internet-Adresse "8.8.8.8" (Googles öffentlicher DNS-Server) zu erreichen. Das Android-Betriebssystem wählt hierzu ein passendes Netzwerk-Interface aus. |
|
Angaben zum zuletzt aufgetretenen Fehler. LastAction: Bezeichnung der Methode, die zuletzt ausgeführt wurde. LastErrorCode: Fehler-Code LastErrorMessage: Fehlerbezeichnung im (englischen) Klartext. |
Ist bei der zuletzt ausgeführten Aktion kein Fehler aufgetreten, hat LastErrorCode den Wert 0 und LastErrorMessage liefert eine leere Zeichenfolge. | |
Methoden | ||
Start startet das "Lauschen" auf Datagramme, die an den angegebenen Port gesendet werden (UDP-Server). | War der Start nicht erfolgreich wird das Ereignis ListenerFailure
ausgelöst. Man sollte keine Portnummern verwenden, die kleiner als 1024 sind. Viele dieser Nummern sind für spezielle Zwecke reserviert. Die Benutzung kann je nach Netzwerkkonfiguration zu Problemen führen. |
|
StartMulticast starts "listening" for datagrams sent by the specified multicast group to the specified port (UDP server). | Man sollte keine Portnummern verwenden, die kleiner als 1024 sind. Viele dieser Nummern sind für spezielle Zwecke reserviert. Die Benutzung kann je nach Netzwerkkonfiguration zu Problemen führen. | |
Stop stoppt den Server. | Ein mehrfaches Aufrufen von Stop ist unkritisch und führt nicht zu einem Fehler. | |
Ereignisse | ||
Das Ereignis ListenerFailure wird ausgelöst, wenn der
Listener-Vorgang nicht gestartet werden konnte oder auf Grund eines Fehlers beendet wurde. ErrorCode: Grund der Beendigung. |
Der Grund kann z.B. der Abbruch einer Netzwerkverbindung sein. | |
Wenn Daten empfangen werden, wird das Ereignis DataReceived
ausgelöst. Data enthält die Datagramm-Daten RemoteIP und RemotePort die Absender-Adresse. |
Code | Meldung | Bedeutung |
---|---|---|
0 | Kein Fehler. | |
6 | Server thread aborted | Der Server-Thread wurde auf Grund eines (Netzwerk-) Fehlers abgebrochen. |
7 | Listener already running | Dieser Listener wurde bereits gestartet. |
8 | Invalid Data Type | Die übergebene Komponente ist nicht vom Typ UrsAI2ByteArray. |
Mit der Version 4.3 wurde das Senden und Empfangen von Binärdaten über die UrsAI2ByteArray-Extension deutlich vereinfacht (s.o.).
Wenn BinaryMode auf true gesetzt ist, akzeptiert Xmit eine Zeichenfolge mit codierten Bytes, die durch ein Komma (’,’) oder ein Semikolon (';') voneinander getrennt sind.
Jedes Byte kann als „0xff“ oder „0xFF“ oder „0Xff“ oder „0XFF“ oder „#ff“ oder „#FF“ für HEX-Input oder „255“ für dezimalen Input oder „0377“ für den Oktal-Input codiert sein.
Man kann die Formate mischen: "0xFF;255,#ff" ist gültig.
Man kann auch Leerzeichen vor und nach der Zahl einfügen: „0xFF; 255, #ff ”ist ebenfalls gültig.
Ein nachfolgendes Komma oder Semikolon wird ignoriert: "0xFF; 255, #ff" und "0xFF; 255, #ff;" sind identisch.
Für die Konvertierung wird dieser Algorithmus verwandt:
Wenn BinaryMode auf true gesetzt ist, wird das empfangene Paket in eine durch Semikola getrennte Zeichenfolge von Dezimalzahlen übersetzt.
Erhält der Listener ein Datagramm mit der Bytefolge (hexadezimal) 48 61 6C 6C 6F, würde dieses normalerweise in den Test "Hallo" übersetzt werden. Bei eingeschaltetem Binärmodus wird "72;97;108;108;111" ausgegeben. Man kann Text.Split verwenden, um eine Liste der Bytes abzurufen:
Texte versenden und empfangen (URSAI2UDPTest)Dieses Bespiel zeigt, wie die Texte versendet und empfangen werden können. |
Die Blöcke im Beispiel sind nicht schwer zu verstehen. Den größten Bereich nimmt die Überprüfung valider Eingaben ein.
Byte-Arrays versenden und empfangen (UDPBinaryTest)Dieses Bespiel zeigt, wie die byte-Arrays versendet und empfangen werden können. |
Im Feld Data werden die zu versenden Bytes als Folge von durch Leerzeichen getrennte zweistellige Hexadezimalzahlen angegeben (ohne führendes "0x"!). Im Beispiel sind dies die ASCII-Codes für den Text "Hello<CRLF>". Im ASCII-Terminal werden die empfangenen Daten in der Text-Repräsentation angezeigt. Vom ASCII-Terminal wurde anschließend der Text "Ulli<CRLF> versendet. Die ASCII-Codes werden in der App hexadezimal angezeigt.
Die Texteingabe wird mit einer Prozedur in die UrsAI2ByteArray-Komponente übertragen:
Für die Erstellung eigener Extensions habe ich einige Tipps zusammengestellt: AI2 FAQ: Extensions entwickeln.
Die Entwicklung der Erweiterungen erfolgt mit Java. Ein Tutorial über Datagramme findet man in der Oracle Java Dokumentation. Dort findet man auch Informationen zur verwendeten Klasse DatagramSocket.