18
Seminarbericht von Marco Rietmann Netzwerk-Programmierung Seminarbericht Netzwerk-Programmierung mit MIDP 2.0 Fachhochschule Nordwestschweiz FHA-Windisch Autor: Marco Rietmann Abteilung: Informatik Betreuung: Prof. Dr. Dominik Gruntz Referat am: 5.1.2005 Seite 1 von 18

Netzwerkprogrammierung mit MIDP - Marco Rietmann · Referat am : 5.1.2005 Seite 1 ... MIDlet can register an inbound connection listener over which the ... Die Klasse DatagramConnection

Embed Size (px)

Citation preview

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

Seminarbericht

Netzwerk-Programmierung mit MIDP 2.0 Fachhochschule Nordwestschweiz FHA-Windisch Autor: Marco Rietmann Abteilung: Informatik Betreuung: Prof. Dr. Dominik Gruntz Referat am: 5.1.2005

Seite 1 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

Abstract1 MIDP 1.0 provided only one core way of connecting to the outside networked world -- an HTTP connection. Version 2.0 expands the connection options available to developers with a number of new network I/O capabilities. As optional low-level networking capabilities for TCP/IP sockets and UDP/IP datagrams are provided. The most interesting capability introduced in the MIDP 2.0 spec is the push registry. A MIDlet can register an inbound connection listener over which the MIDlet can be activated when it is not running. This way, a MIDlet can provide services even when it is not actively running. This seminar report explains these new features.

1 Written by Dominik Gruntz

Seite 2 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

Inhaltsverzeichnis 1 Erweiterungen von MIDP 2.0 im Überblick ........................................................................... 4

1.1 MIDP 1.0.......................................................................................................................... 4 1.2 MIDP 2.0.......................................................................................................................... 5

2 TCP-Verbindung ..................................................................................................................... 6 2.1 Client ................................................................................................................................ 7

2.1.1 SocketConnection: .................................................................................................... 7 2.1.2 Input- und Outputstream: .......................................................................................... 8

2.2 Server ............................................................................................................................... 9 2.2.1 Erstellen einer ServerSocketConnection................................................................... 9 2.2.2 Die Methode acceptAndOpen() ................................................................................ 9

3 UDP-Verbindungen............................................................................................................... 10 3.1 DatagramConnection...................................................................................................... 10 3.2 Datagram ........................................................................................................................ 11

3.2.1 Datagram senden ..................................................................................................... 11 3.2.2 Datagram empfangen .............................................................................................. 11

4 Swisscom GPRS.................................................................................................................... 12 5 Konzepte für den Aufbau einer Natel Natel-Verbindung ................................................ 13

5.1 Mit Hilfe eines Webservers:........................................................................................... 13 5.2 Mit SMS: ........................................................................................................................ 14

6 Push Registry......................................................................................................................... 15 6.1 Statische Registrierung................................................................................................... 15 6.2 Dynamische Registrierung ............................................................................................. 16 6.3 Alarm-Registrierung....................................................................................................... 17

6.2.1 Die SMS Variante mit der Push Registry: .............................................................. 17 7 Literaturverzeichnis............................................................................................................... 18

Seite 3 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

1 Erweiterungen von MIDP 2.0 im Überblick In MIDP 1.0 waren die Funktionalitäten bezüglich Netzwerk sehr eingeschränkt. Es waren nur HTTP-Verbindungen möglich. In MIDP 2.0 wurden die Möglichkeiten stark erweitert. Die Programmierung von UDP- und TCP Servern und Clients ist nun möglich. Ebenfalls werden Verbindungen über die Seriell- und Infrarotschnittstelle unterstützt. Eine zweite gravierende Erneuerung ist die Push Registry. Die Push Registry ist eine vom Gerät verwaltete Tabelle, in welcher man MIDlets eintragen kann, die auf bestimmte Ereignisse gestartet werden, wie zum Beispiel das Ankommen eines UDP Paketes, einer TCP-Verbindung oder eines SMS.

1.1 MIDP 1.0

Bild 1 In MIDP 1.0 kann die Factory-Klasse Connector nur HTTP-Verbindungen aufbauen. Die Methode Connection Connector.open(String url)öffnet eine HTTP-Verbindung zur angegebenen URL. Sie wurde schon in MIDP 1.0 so konzipiert, dass sie auch weitere Verbindungen öffnen kann. Deswegen hat sie den Rückgabetyp Connection. Wie man im Bild 1 erkennen kann, sind alle Verbindungen von diesem Interface abgeleitet. Beispiel für das Erstellen einer HTTP-Verbindung in MIDP 1.0 Connection c = (HttpConnection)Connector.open(“http://www.yahoo.com/”);

Seite 4 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

1.2 MIDP 2.0

Bild 2 In MIDP 2.0 kann die Methode Connector.open(String url)mehrere verschiedene Connection-Typen erstellen. Hier eine Tabelle mit einigen Möglichkeiten: URL Rückgabe Interface Protokoll socket://host:port SocketConnection TCP (Client) socket://:port ServerSocketConnection TCP (Server) ssl://host:port SecureConnection SSL/TLS datagram://host:port UDPDatagramConnection UDP datagram://:port UDPDatagramConnection UDP http://host:port/file?querry HttpConnection HTTP https://host:port/file?query HttpsConnection HTTPS comm://port;parameters CommConnection Seriell / Infrarot

Seite 5 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

Wie man in Bild 2 erkennen kann, sind auch in MIDP 2.0 alle Verbindungsinterfaces von der Connection-Klasse abgeleitet. Je nach Gerät sind weitere optionale Verbindungsmöglichkeiten vorhanden, zum Beispiel folgende aus dem WMA-Package. Mit diesen Verbindungsvarianten können SMS und MMS versendet und empfangen werden. URL Rückgabe Interface Protokoll sms://phoneNumber:port MessageConnection SMS an ein MIDlet sms://phoneNumber MessageConnection SMS normal sms://:port MessageConnection SMS empfangen mms://phoneNumber MessageConnection MMS normal Die Methode Connection.open() erlaubt auch die Einschränkung auf nur Lesen oder nur Schreiben. Connector.open(URL,Connector.READ) Connector.open(URL,Connector.WRITE) Ebenfalls kann angegeben werden, ob das MIDlet Timeouts behandeln kann oder nicht. Connector.open(URL,Connector.READ_WRITE, true) //Timouts Connector.open(URL,Connector.READ_WRITE, false) //Keine Timeouts Der Timeout-Intervall lässt sich jedoch nicht einstellen.

2 TCP-Verbindung

Bild 3 Beim Transmission-Control-Protokoll wird eine Verbindung zwischen zwei Geräten aufgebaut. Es gibt, den Server, welcher auf eine eingehende Verbindung wartet, und einen oder mehrere Clients, welche eine Verbindung zum Server aufbauen (siehe Bild 3). Über einen Input- und einen OutputStream können jeweils Daten gesendet und empfangen werden. Das Protokoll stellt die Reihenfolge und die Richtigkeit der Daten sicher.

Seite 6 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

2.1 Client try { //2.1.1 sc = (SocketConnection) Connector.open("socket://localhost:5000"); //2.1.2 is = sc.openInputStream(); os = sc.openOutputStream(); os.write("hallo".getBytes()); os.flush(); //Stellt sicher, dass alle Daten gesendet wurden StringBuffer sb = new StringBuffer(); int c = 0; while (((c = is.read())!= -1)) { sb.append((char) c); } } catch (Exception e) { e.printStackTrace(); } finally{ try { //Schliessen der Verbindungen os.close(); is.close(); sc.close(); }catch (Exception e) { e.printStackTrace(); } } Code Beispiel 1

2.1.1 SocketConnection: Eine TCP-Verbindung startet man mit der URL socket://host:port. Da Connector.open() den Typ Connection hat, muss der Rückgabewert noch in eine SocketConnection geparst werden. Im Objekt SocketConnection können einige Optionen gesetzt werden. Dies wird mit der Methode setSocketOption (byte option, int wert) gemacht. Mit getSocketOption(byte option) können die Einstellungen wieder ausgelesen werden. Die Möglichkeiten sind in folgender Tabelle festgehalten.

Option (byte) Beschreibung SocketConnection.DELAY Schaltet den so genannten Nagle-Algorithmus ein oder

aus. Mögliche Werte: 0 = aus, nicht 0 = ein. Dieser Algorithmus sammelt erst einige Daten, bevor er sie weitersendet. Er verhindert somit einen grossen Overhead bei kleinen Datenmengen.

SocketConnection.KEEPALIVE Sendet periodisch leere Segmente, um die Verbindung aufrechtzuerhalten. Mögliche Werte: 0 = aus, nicht 0 = ein.

SocketConnection.LINGER Setzt die Zeitdauer, welche beim Schliessen der TCP-Verbindung abgewartet werden soll, bis im Sende-Buffer liegende Daten geschickt wurden.

SocketConnection.RCVBUF Der TCP-Implementierung wird für den Empfangs-Buffer eine Länge in Bytes vorgeschlagen.

SocketConnection.SENDBUF Der TCP-Implementierung wird für den Sendebuffer eine Länge in Bytes vorgeschlagen.

Seite 7 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

Mit folgenden Methoden können die Adressen und Ports aus der Klasse SocketConnection gelesen werden. getAddress() getPort() getLocalAddress() getLocalPort()

2.1.2 Input- und Outputstream: Die SocketConnection stellt einen Input- und einen OutputStream bereit. Über den OutputStream können Daten gesendet, über den InputStream empfangen werden. Die Streams können wie folgt aus der SocketConnection geholt werden. openInputStream() openDataInputStream() openOutputStream() openDataOutputStream() In speziellen Fällen können diese Methoden auch direkt auf der Connector-Klasse aufgerufen werden. Man erspart sich dadurch einige Zeilen Code. Diesen gleichnamigen Methoden der Klasse Connector muss man aber noch die URL als Parameter angeben. Mit der Klasse OutputStream können Zeichen über die Verbindung geschickt werden. Dies kann mit folgenden Methoden erreicht werden (siehe auch Code Beispiel 1): write(int); write(bytes[], int, int) write(bytes[]); Mit der Klasse DataOutputStream können zusätzlich zu den Zeichen auch verschiedene andere Datentypen versendet werden. Wie an den zur Verfügung stehenden Methoden erkannt werden kann. write(int); write(bytes[], int, int) writeBoolean(boolean arg) writeShort(int arg) writeChar(int arg) writeInt(int arg) writeLong(long arg) writeChars(String arg) writeUTF(String arg) writeUTF(String arg, DataOutput arg) Analog dazu die Klassen InputStream und DataInputStream mit den read-Methoden. readBoolean(); readShort(); u.s.w.

Seite 8 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

2.2 Server try { //2.2.1 scn = (ServerSocketConnection) Connector.open("socket://:5000"); //2.2.2 sc = (SocketConnection) scn.acceptAndOpen(); //2.1.2 is = sc.openInputStream(); os = sc.openOutputStream(); StringBuffer sb = new StringBuffer(); int c = 0; for(i=0; i<5; i++){ sb.append((char) c); } if(sb.toString().equals(“hallo”)){ os.write("hallo".getBytes()); } } catch (Exception e) { e.printStackTrace(); } finally{ try { //Schliessen der Verbindungen os.close(); is.close(); sc.close(); scn.close(); }catch (Exception e) { e.printStackTrace(); } } Code Beispiel 2 Dieser Server ist das Gegenstück zu dem in Code Beispiel 1 beschriebenen Clienten.

2.2.1 Erstellen einer ServerSocketConnection Wenn man in der URL keine Adresse angibt, bekommt man von der Methode Connector.open() eine ServerSocketConnection zurück. Die ServerSocketConnection hängt sich an den angegebenen Port und wartet auf eingehende Verbindungen. Diese werden von der Methode acceptAndOpen() zurückgegeben.

2.2.2 Die Methode acceptAndOpen() In der Methode acceptAndOpen() wird auf eine eingehende Verbindung gewartet. Wenn eine solche eintrifft, wird eine SocketConnection zurückgegeben. In einem richtigen Server würde man diese in der run()-Methode eines Threads, in einer while(true)-Schleife warten lassen. Nach dem Zustandekommen der Verbindung wird dann ein neuer Thread gestartet (Code Beispiel 3).

Seite 9 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

public void run(){ try { while(true){ scn = (ServerSocketConnection) Connector.open("socket://:5000"); Thread t = new Thread(new Verbindung(scn.acceptAndOpen())); t.start(); } }catch(Exception e){ ..... } } Code Beispiel 3

3 UDP-Verbindungen Das User-Datagram-Protokoll erstellt keine Verbindung, es unterstützt lediglich das Senden und Empfangen von maximal 64Kb grossen Datagram-Paketen. Es wird nur die Richtigkeit des Inhaltes jeden Datagram-Paketes garantiert, nicht aber, ob es ankomme. Auch wird die Reihenfolge, in der die Pakete eintreffen, nicht garantiert. //3.1 DatagramConnection dc = (DatagramConnection) Connector.open("datagram://:5555"); try { //3.2.1 byte[] bytes = “hallo”.getBytes(); dg = dc.newDatagram(bytes, bytes.length, address); dc.send(dg); //3.2.2 Datagram dg = dc.newDatagram(100); dc.receive(dg); si.setText("Message received - " + new String(dg.getData(), 0, dg.getLength())); } catch (Exception e) { e.printStackTrace(); } Code Beispiel 4

3.1 DatagramConnection Die Klasse DatagramConnection ist vergleichbar mit der DatagramSocket der Java Standardedition. Das Wort Connection kommt von dem Connection Framework, hat aber nichts mit einer Verbindung zu tun, denn UDP ist verbindungslos. Es gibt zwei Varianten, eine DatagramConnection zu erstellen. Bei der einen gibt man gleich eine Adresse mit: Connector.open(„datagram://adresse:port“). Das ist geeignet, wenn man mit dieser DatagramConnection nur mit einem einzigen Rechner kommunizieren will. Bei der anderen Variante erstellt man eine DatagramConnection ohne Adresse. Connector.open(„datagram://:port“) Der Port wird als Ziel für die Pakete verwendet. Ebenfalls werden Pakete auf diesem Port empfangen. Die Connector.open()-Methode gibt so eine UDPDatagramConnection zurück, welche das Interface DatagramConnection implementiert (siehe Code Beispiel). Es wäre auch folgender Aufruf möglich:

Seite 10 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

UDPDatagramConnection dc = (UDPDatagramConnection) Connector.open("datagram://:5555"); Mit der DatagramConnection können Pakete (Datagramme) erstellt und verschickt werden. Dafür werden folgende Methoden angeboten. int getMaximumLength() int getNominalLanght() Datagram newDatagram(byte[] buf, int size) Datagram newDatagram(byte[] buf, int size, String address) Datagram newDatagram(int size) Datagram newDatagram(int size, String address) void receive(Datagram dgram) void send(Datagram dgram) Die UDPDatagramConnection lässt zusätzlich weitere Methoden zu, die den lokalen Port und die lokale Adresse zurückgeben. String getLocalAddress() int getLocalPort()

3.2 Datagram Methoden: String getAddress() Byte[] getData() Int getLength() Int getOffset() Void reset() Void setAddress(Datagram reference) Void setAddress(String address) setData(byte[] buffer, int offset, int Length) setLength(int length) Zusätzlich unterstützt das Datagram auch fast alle Schreibmethoden des DataOutputStream- und alle Lesemethoden des DataInputStream-Interfaces (siehe 2.1.2).

3.2.1 Datagram senden Mit der Methode newDatagram(byte[] buf, int size) wird ein neues Datagram erzeugt. Dieses enthält die Zieladresse des DatagramConnection-Objektes. Mit der Methode newDatagram(byte[] buf, int size, string address) kann ein neues Datagram mit eigener Zieladresse erzeugt werden. Das Datagram kann mit der send()-Methode verschickt werden (siehe Code Beispiel 4).

3.2.2 Datagram empfangen Zum Empfangen eines Datagrams muss zuerst ein leeres Datagram angelegt werden. Ein Datagram kann mit der Methode newDatagram(int size) erstellt werden. Hier wird eine maximale Grösse der zu empfangenden Daten festgelegt. Das Datagram kann nun in der receive()-Methode mit den zu empfangenden Daten aufgefüllt werden (siehe Code Beispiel 4).

Seite 11 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

4 Swisscom GPRS

Bild 4 Im Swisscom GPRS-Netz werden die Adressen der Natels dynamisch verteilt. Jedes Natel, das sich auf das GPRS-Netz einwählt, erhält eine Private-Network-IP-Adresse der Klasse A. Also: 10. * . * . * Dieses Private Network wird über den GGSN (Gateway GPRS Support Node) in das Internet geroutet. Dieser GGNS besteht aus verschiedenen Routern und Firewalls (siehe Bild 4). Mit dieser Infrastruktur sind folgende Verbindungsvarianten möglich:

• GPRS WWW • GPRS GPRS (ohne Aktivierung im GGNS nicht möglich.)

Da die IP-Adressen dynamisch vergeben werden und nicht mit den jeweiligen Nummern verknüpft sind, benötigt man spezielle Konzepte für den Verbindungsaufbau (siehe Kapitel 5)

• Die Verbindung WWW GPRS wird momentan aus Sicherheitsgründen noch nicht unterstützt.

Seite 12 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

5 Konzepte für den Aufbau einer Natel Natel-Verbindung

5.1 Mit Hilfe eines Webservers:

Bild 5 Hierfür braucht es einen Webserver mit einer Datenbank und fester, bekannter Adresse. Jedes Server-Natel sendet seine Adresse und seinen Namen dem Webserver, und dieser speichert sie in der Datenbank. Wenn nun ein Client-Natel zu einem Server-Natel eine Verbindung aufbauen will, muss es zuerst den Webserver nach der Adresse des Server-Natels fragen (siehe Bild 5).

Seite 13 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

5.2 Mit SMS:

Bild 6 In diesem Konzept sind die Funktionen von Client und Server vertauscht. Hier baut der Server die Netzwerkverbindung zum Client auf. Der Server wird sozusagen zum Mehrfachclient und der Client zum Einfachserver. Auf ein SMS, das die Clientadresse beinhaltet, erstellt der Server eine Verbindung mit dem Client (siehe Bild 5).

Seite 14 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

6 Push Registry Die Push Registry besteht aus einer in jedem MIDP-2.0-fähigen System eingebauten Tabelle. Wenn nun eine Verbindung mit dem Gerät erstellt wird, wird zuerst in der Tabelle nachgeschaut. Existiert für diese Verbindung ein passender Eintrag, wird das entsprechende MIDlet gestartet. Wenn ein MIDlet auf das Eingehen einer Verbindung gestartet werden soll, braucht es einen Eintrag in dieser Tabelle. Er werden grundsätzlich alle Verbindungen unterstützt, welche auch von der Connector.open() -Methode unterstützt werden. Die Tabelle sieht folgendermassen aus: URL Klassenname Allowed Sender socket://:5000 MyMidlet 147.86.*.* datagramm://5001 MyMidlet * sms://:1000 MyMidlet +4156*

• URL repräsentiert die selbe URL, die danach durch den Connector.Open()-Aufruf verwendet wird.

• Klassenname: Der vollqualifizierte Klassenname des zu startenden MIDlets.

• Allowed Sender spezifiziert die Adressen der erlaubten Kommunikationspartner. Es

werden folgende Platzhalter erlaubt: o ? steht für ein einzelnes Zeichen o * steht für mehrere Zeichen

Es gibt zwei Möglichkeiten, wie sich ein MIDlet in der Push Registry eintragen kann: Die statische Registrierung und die dynamische Registrierung.

6.1 Statische Registrierung Das MIDlet wird bei der Installation in die Push Registry Tabelle eingetragen. Diese Eintragungen müssen im Applikationsdescriptor angegeben werden. Man kann dies jedoch relativ einfach mit dem Wireless Toolkit erledigen. Hierfür muss man auf „Settings“ klicken und dann auf den Tab „Push Registry“ wechseln (siehe Bild 7). Hier können die Eintragungen spezifiziert werden, welche bei der Installation in der Push Registry vorgenommen werden sollen.

Seite 15 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

Bild 7

6.2 Dynamische Registrierung Bei der Dynamischen Registrierung wird ein MIDlet während der Laufzeit in die Push Registry eingetragen. Dafür wird die Klasse PushRegistry verwendet. Diese stellt folgende Methoden zur Verfügung:

• String getFilter(String connection) Liefert den „Allowed Sender“ Wert zurück.

• String getMIDlet(String connection) Liefert den Klassennamen des MIDlets zurück.

• String[] listConnections(boolean available) o Available = false: Liefert alle zum aufrufenden MIDlet eingetragenen

Connections. o Available = true: Liefert nur diejenigen Connections, an welchen Input anliegt.

• void registerConnection(String connections, String midlet, String filter) erstellt einen neuen Eintrag in die Push Registry.

• boolean unregisterConnection(String connection) Löscht einen Eintrag. o false, wenn Eintrag nicht existiert. o SecurityException: Wenn Eintrag existiert, aber nicht entfernt werden darf.

Seite 16 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

6.3 Alarm-Registrierung Dies ist ein weiterer Mechanismus, womit ein MIDlet gestartet werden kann. Dieser kann nur mit der dynamischen Variante verwendet werden. Das MIDlet wird zu einem bestimmten Zeitpunkt wieder gestartet. Es kann im Gegensatz zu der Connection-Registrierung pro MIDlet nur ein Eintrag in die Push Registry abgelegt werden. Die Klasse PushRegistry stellt hierfür auch nur eine einzige Methode zur Verfügung: long registerAlarm(String midlet, long time) Der Rückgabewert ist die alte Zeit. Der erste Parameter ist die Klasse des MIDlets. Der zweite Parameter ist die neue Zeit, bei der das MIDlet gestartet werden soll. Ist der zweite Parameter 0, wird das MIDlet aus der Push Registry entfernt. Hinweis: Die Zeit wird in Millisekunden angegeben. Die aktuelle Zeit kann mit long System.currentTimeMillis() geholt werden.

6.2.1 Die SMS Variante mit der Push Registry: Bei der SMS Variante kann man beim Server relativ einfach die Push Registry verwenden. Hierfür ist die statische Registrierung vorzuziehen. Das ergibt in den Settings unter Push Registry folgenden Eintrag: Kye Connection URL Class AllowedSender MIDlet-push-1 sms://:1000 smscon.MyServer * Nach der Installation wird nach Erhalt eines SMS auf dem Port 1000 automatisch die Serverapplikation smscon.MyServer gestartet und eine Verbindung zum Client aufgebaut. Damit die Push Registry mit dem Wireless Toolkit getestet werden kann, muss die Applikation mit Projekt run via OTA gestartet werden. Das geht folgendermassen:

1. Project Build 2. Project Package Create Package 3. Project run via OTA

Seite 17 von 18

Seminarbericht von Marco Rietmann Netzwerk-Programmierung

7 Literaturverzeichnis Wireless Toolkit: MIDP API Dokumentation. Weblinks: http://developers.sun.com/techtopics/mobility/midp/articles/pushreg/http://www.corej2me.com/DeveloperResources/IBM/pushtechnology.pdfhttp://jan.netcomp.monash.edu.au/internetdevices/wireless/wma.html Buch: Java 2 Micro Edition von Klaus-Dieter Schmatz 1.Auflage 2004

Seite 18 von 18