Sockets
Flash Player 9 und höher, Adobe AIR 1.0 und höher
Ein Socket ist eine bestimmte Art von Netzwerkverbindung zwischen zwei Computerprozessen. Normalerweise werden die Prozesse auf zwei verschiedenen Computern ausgeführt, die mit demselben IP-Netzwerk verbunden sind. Die verbundenen Prozesse können jedoch auf demselben Computer ausgeführt werden, wobei die spezielle IP-Adresse für den „lokalen Host“ verwendet wird.
Adobe Flash Player unterstützt clientseitige TCP-Sockets (Transport Control Protocol). Eine Flash Player-Anwendung kann eine Verbindung mit einem anderen Prozess herstellen, der als Socket-Server agiert, aber keine eingehenden Verbindungsanforderungen von anderen Prozessen entgegennehmen. Anders ausgedrückt: Eine Flash Player-Anwendung kann eine Verbindung mit einem TCP-Server herstellen, aber nicht als TCP-Server fungieren.
Die Flash Player-API enthält auch die XMLSocket-Klasse. Die XMLSocket-Klasse verwendet ein spezifisches Flash Player-Protokoll, das den Austausch von XML-Nachrichten mit einem Server ermöglicht, der dieses Protokoll interpretieren kann. Die XMLSocket-Klasse wurde in ActionScript 1 eingeführt und wird zur Gewährleistung der Abwärtskompatibilität auch weiterhin unterstützt. Im Allgemeinen sollte für neue Anwendungen die Socket-Klasse verwendet werden, es sei denn, Sie stellen eine Verbindung mit einem Server her, der konkret für die Kommunikation mit Flash XMLSockets eingerichtet wurde.
In Adobe AIR stehen mehrere zusätzliche Klassen für die socketbasierte Netzwerkprogrammierung zur Verfügung. AIR-Anwendungen können mit der ServerSocket-Klasse als TCP-Socket-Server agieren und über die SecureSocket-Klasse Verbindungen mit Socket-Servern herstellen, die SSL- oder TLS-Sicherheit erfordern. AIR-Anwendungen können auch UDP-Nachrichten (Universal Datagram Protocol) über die DatagramSocket-Klasse senden und empfangen.
TCP-Sockets
Das TCP-Protokoll (Transmission Control Protocol) bietet die Möglichkeit, Nachrichten über eine dauerhafte Netzwerkverbindung auszutauschen. TCP gewährleistet, dass die gesendeten Nachrichten in der richtigen Reihenfolge eingehen (sofern keine größeren Netzwerkprobleme vorliegen). TCP-Verbindungen erfordern einen Client und einen Server. Flash Player kann Client-Sockets erstellen. Adobe AIR kann zudem Server-Sockets erstellen.
Die folgenden ActionScript-APIs ermöglichen TCP-Verbindungen:
-
Socket – ermöglicht einer Client-Anwendung, eine Verbindung mit einem Server herzustellen. Die Socket-Klasse kann nicht auf eingehende Verbindungen warten.
-
SecureSocket (AIR) – ermöglicht einer Client-Anwendung, eine Verbindung mit einem vertrauenswürdigen Server herzustellen und eine verschlüsselte Kommunikation durchzuführen.
-
ServerSocket (AIR) – ermöglicht einer Anwendung, auf eingehende Verbindungen zu warten und als Server zu agieren.
-
XMLSocket – ermöglicht einer Client-Anwendung, eine Verbindung mit einem XMLSocket-Server herzustellen.
Binäre Clientsockets
Eine binäre Socketverbindung ähnelt einem XML-Socket, außer dass Client und Server nicht auf den Austausch von XML-Nachrichten beschränkt sind. Stattdessen kann die Verbindung Daten als binäre Informationen übertragen. Dadurch können Verbindungen mit zahlreichen Diensten hergestellt werden, einschließlich Mailserver (POP3, SMTP und IMAP) und News-Server (NNTP).
Socket-Klasse
Die Socket-Klasse ermöglicht die Herstellung von Socketverbindungen sowie das Lesen und Schreiben von unformatierten Binärdaten. Die Socket-Klasse eignet sich gut für die Arbeit mit Servern, die Binärprotokolle verwenden. Durch die Verwendung von binären Socketverbindungen können Sie Code schreiben, der mit mehreren verschiedenen Internetprotokollen interagiert, wie POP3, SMTP, IMAP und NNTP. Diese Interaktion ermöglicht es Ihren Anwendungen, eine Verbindung zu Mailservern und News-Servern herzustellen.
Flash Player kann bei der Datenübertragung mit einem Server direkt das Binärprotokoll dieses Servers verwenden. Einige Server verwenden die Byte-Reihenfolge „big-endian“ und andere die Byte-Reihenfolge „little-endian“. Die meisten Server im Internet verwenden die Byte-Reihenfolge „big-endian“, da dies der Byte-Reihenfolge in Netzwerken entspricht. Die Bytereihenfolge littleEndian ist verbreitet, da sie in der Intel® x86-Prozessorarchitektur verwendet wird. Sie sollten die Byte-Reihenfolge verwenden, die der Byte-Reihenfolge des Servers entspricht, der die Daten sendet oder empfängt. Alle Vorgänge, die von den Schnittstellen „IDataInput“ und „IDataOutput“ ausgeführt werden, und die Klassen, die diese Schnittstellen implementieren (ByteArray, Socket und URLStream), liegen standardmäßig im bigEndian-Format vor, dabei steht das höchstwertige Byte an erster Stelle. Diese standardmäßige Byte-Reihenfolge wurde wegen der Übereinstimmung mit Java und der offiziellen Byte-Reihenfolge für Netzwerke (Network Byte Order) gewählt. Um von der bigEndian- zur littleEndian-Bytereihenfolge oder umgekehrt zu wechseln, stellen Sie die
endian
-Eigenschaft auf
Endian.BIG_ENDIAN
oder
Endian.LITTLE_ENDIAN
ein.
Die Socket-Klasse übernimmt alle Methoden, die von den IDataInput- und IDataOutput-Schnittstellen definiert werden (im flash.utils-Paket). Diese Methoden müssen für Lese- und Schreibvorgänge mit den Sockets verwendet werden.
Weitere Informationen finden Sie unter:
Sichere Clientsockets (AIR)
Mithilfe der SecureSocket-Klasse können Sie Verbindungen mit Socketservern herstellen, die SSL-Version 4 (Secure Sockets Layer) oder TLS-Version 1 (Transport Layer Security) verwenden. Sichere Sockets bieten drei Vorteile: Serverauthentifizierung, Datenintegrität und Vertraulichkeit der Nachrichten. Die Laufzeit authentifiziert einen Server anhand des Serverzertifikats und der Beziehung des Servers mit den Stamm- oder Zwischenzertifikaten der entsprechenden Zertifizierungsstellen im Vertrauensspeicher des Benutzers. Zur Gewährleistung von Datenintegrität und Vertraulichkeit der Nachrichten stützt sich die Laufzeit auf die Verschlüsselungsalgorithmen der SSL- und TLS-Protokollimplementierungen.
Wenn Sie über das SecureSocket-Objekt eine Verbindung mit einem Server herstellen, validiert die Laufzeit das Serverzertifikat anhand des Zertifikatvertrauensspeichers. Unter Windows und Mac stellt das Betriebssystem den Vertrauensspeicher bereit. Unter Linux bietet die Laufzeitumgebung einen eigenen Vertrauensspeicher.
Wenn das Serverzertifikat nicht gültig oder vertrauenswürdig ist, gibt die Laufzeit ein
ioError
-Ereignis aus. Anhand der
serverCertificateStatus
-Eigenschaft des SecureSocket-Objekts können Sie überprüfen, warum die Validierung fehlgeschlagen ist. Für Server ohne gültiges und vertrauenswürdiges Zertifikat steht kein Kommunikationsmechanismus zur Verfügung.
Die CertificateStatus-Klasse definiert Stringkonstanten für die möglichen Validierungsergebnisse:
-
Expired – Das Zertifikat ist abgelaufen.
-
Invalid – Das Zertifikat ist ungültig. Dies kann mehrere Gründe haben. Beispielsweise wurde das Zertifikat geändert oder beschädigt oder es hat nicht den richtigen Typ.
-
Invalid chain – Mindestens ein Zertifikat in der Zertifikatkette des Servers ist ungültig.
-
Principal mismatch – Der Hostname des Servers und der Zertifikatname stimmen nicht überein. Der Server verwendet also das falsche Zertifikat.
-
Revoked – Die ausgebende Zertifizierungsstelle hat das Zertifikat gesperrt.
-
Trusted – Das Zertifikat ist gültig und vertrauenswürdig. Ein SecureSocket-Objekt kann nur eine Verbindung mit einem Server herstellen, der ein gültiges, vertrauenswürdiges Zertifikat verwendet.
-
Unknown – Das SecureSocket-Objekt hat das Zertifikat noch nicht validiert. Die
serverCertificateStatus
-Eigenschaft hat diesen Statuswert, bevor Sie
connect()
aufrufen und bevor entweder ein
connect
- oder ein
ioError
-Ereignis ausgelöst wird.
-
Untrusted signers – Das Zertifikat ist nicht mit einem vertrauenswürdigen Stammzertifikat im Vertrauensspeicher des Clientcomputers „verkettet“.
Für die Kommunikation mit einem SecureSocket-Objekt muss der Server ein sicheres Protokoll verwenden und über ein gültiges und vertrauenswürdiges Zertifikat verfügen. In jeder anderen Hinsicht entspricht die Verwendung eines SecureSocket-Objekts der Verwendung eines Socket-Objekts.
Das SecureSocket-Objekt wird nicht auf allen Plattformen unterstützt. Verwenden Sie die
isSupported
-Eigenschaft der SecureSocket-Klasse, um zu überprüfen, ob die Laufzeitumgebung die Verwendung des SecureSocket-Objekts auf dem aktuellen Clientcomputer unterstützt.
Weitere Informationen finden Sie unter:
TCP-Socket-Beispiel: Erstellen eines Telnet-Clients
Das Telnet-Beispiel demonstriert Techniken für das Herstellen einer Verbindung mit einem Remote-Server und das Übertragen von Daten mithilfe der Socket-Klasse. In diesem Beispiel werden die folgenden Verfahren veranschaulicht:
-
Erstellen eines benutzerdefinierten Telnet-Clients mithilfe der Socket-Klasse
-
Senden von Text an den Remote-Server mithilfe eines ByteArray-Objekts
-
Verarbeiten der von einem Remote-Server empfangenen Daten
Die Anwendungsdateien für dieses Beispiel finden Sie unter
www.adobe.com/go/learn_programmingAS3samples_flash_de
. Die Dateien der Telnet-Anwendung finden Sie im Ordner „Samples/Telnet“. Die Anwendung umfasst die folgenden Dateien:
Datei
|
Beschreibung
|
TelnetSocket.fla
oder
TelnetSocket.mxml
|
Die Hauptanwendungsdatei mit der Benutzeroberfläche für Flex (MXML) oder Flash (FLA).
|
TelnetSocket.as
|
Document-Klasse, die die Benutzeroberflächenlogik bereitstellt (nur Flash).
|
com/example/programmingas3/Telnet/Telnet.as
|
Stellt die Telnet-Clientfunktionsmerkmale für die Anwendung bereit. Hierzu gehören das Herstellen einer Verbindung mit einem Remote-Server sowie das Senden, Empfangen und Anzeigen von Daten.
|
Überblick über die Anwendung „TelnetSocket“
Mit der Hauptdatei „TelnetSocket.mxml“ wird die Benutzeroberfläche (User Interface, UI) der gesamten Anwendung erstellt.
Zusätzlich zur Benutzeroberfläche sind in dieser Datei die beiden Methoden
login()
und
sendCommand()
definiert, mit denen eine Verbindung zwischen Benutzer und angegebenem Server hergestellt wird.
Im Folgenden ist der ActionScript-Code der Hauptanwendungsdatei aufgeführt:
import com.example.programmingas3.socket.Telnet;
private var telnetClient:Telnet;
private function connect():void
{
telnetClient = new Telnet(serverName.text, int(portNumber.text), output);
console.title = "Connecting to " + serverName.text + ":" + portNumber.text;
console.enabled = true;
}
private function sendCommand():void
{
var ba:ByteArray = new ByteArray();
ba.writeMultiByte(command.text + "\n", "UTF-8");
telnetClient.writeBytesToSocket(ba);
command.text = "";
}
Mit der ersten Codezeile wird die Telnet-Klasse aus dem benutzerdefinierten com.example.programmingas.socket-Paket importiert. Mit der zweiten Codezeile wird eine Instanz der Telnet-Klasse deklariert,
telnetClient
, die später von der
connect()
-Methode initialisiert wird. Dann wird die
connect()
-Methode deklariert und die zuvor deklarierte Variable
telnetClient
initialisiert. Diese Methode übergibt den benutzerdefinierten Telnet-Servernamen „telnet server port“ und einen Verweis auf die TextArea-Komponente an die Anzeigeliste, die zur Anzeige der Textantworten vom Socketserver verwendet wird. Die letzten beiden Zeilen der
connect()
-Methode stellen die
title
-Eigenschaft für das Panel ein und aktivieren die Panel-Komponente, die es dem Benutzer ermöglicht, Daten an den Remote-Server zu senden. Die letzte Methode in der Hauptanwendungsdatei,
sendCommand()
, dient zum Senden der Benutzerbefehle als ein ByteArray-Objekt an den Remote-Server.
Überblick über die Telnet-Klasse
Die Telnet-Klasse ist für das Herstellen einer Verbindung mit dem externen Telnet-Server und das Senden/Empfangen von Daten verantwortlich.
Die Telnet-Klasse deklariert die folgenden privaten Variablen:
private var serverURL:String;
private var portNumber:int;
private var socket:Socket;
private var ta:TextArea;
private var state:int = 0;
Die erste Variable,
serverURL
, enthält die vom Benutzer eingegebene Serveradresse, mit der eine Verbindung hergestellt werden soll.
Die zweite Variable
portNumber
ist die Nummer des Anschlusses, auf dem der Telnet-Server derzeit ausgeführt wird. In der Standardeinstellung befindet sich der Telnet-Dienst auf dem Anschluss 23.
Die dritte Variable
socket
ist eine Socket-Instanz, die versucht, eine Verbindung mit dem von den Variablen
serverURL
und
portNumber
angegebenen Server herzustellen.
Die vierte Variable
ta
ist ein Verweis auf eine Instanz der TextArea-Komponente auf der Bühne. Diese Komponente dient zum Anzeigen der Antworten vom externen Telnet-Server sowie aller möglicher Fehlermeldungen.
Die letzte Variable,
state
, ist ein numerischer Wert, mit dem festgestellt wird, welche Optionen Ihr Telnet-Client unterstützt.
Wie Sie bereits gesehen haben, wird die Konstruktorfunktion der Telnet-Klasse von der
connect()
-Methode in der Hauptanwendungsdatei aufgerufen.
Der Telnet-Konstruktor lässt drei Parameter zu:
server
,
port
und
output
. Die Parameter
server
und
port
geben den Servernamen und die Anschlussnummer an, auf welcher der Telnet-Server ausgeführt wird. Der letzte Parameter,
output
, ist ein Verweis auf die Instanz einer TextArea-Komponente auf der Bühne, in der die Serverausgabe angezeigt wird.
public function Telnet(server:String, port:int, output:TextArea)
{
serverURL = server;
portNumber = port;
ta = output;
socket = new Socket();
socket.addEventListener(Event.CONNECT, connectHandler);
socket.addEventListener(Event.CLOSE, closeHandler);
socket.addEventListener(ErrorEvent.ERROR, errorHandler);
socket.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
socket.addEventListener(ProgressEvent.SOCKET_DATA, dataHandler);
Security.loadPolicyFile("http://" + serverURL + "/crossdomain.xml");
try
{
msg("Trying to connect to " + serverURL + ":" + portNumber + "\n");
socket.connect(serverURL, portNumber);
}
catch (error:Error)
{
msg(error.message + "\n");
socket.close();
}
}
Schreiben von Daten an eine Socketverbindung
Zum Schreiben von Daten an eine Socketverbindung rufen Sie eine der Schreibmethoden (write) der Socket-Klasse auf. Zu diesen Schreibmethoden zählen
writeBoolean()
,
writeByte()
,
writeBytes()
und
writeDouble()
. Dann löschen Sie die Daten mit der
flush()
-Methode aus dem Ausgabepuffer. Im Telnet-Server werden Daten mithilfe der
writeBytes()
-Methode an die Socketverbindung geschrieben. Die Methode verarbeitet das Byte-Array als einen Parameter und sendet ihn an den Ausgabepuffer. Die
writeBytesToSocket()
-Methode lautet folgendermaßen:
public function writeBytesToSocket(ba:ByteArray):void
{
socket.writeBytes(ba);
socket.flush();
}
Diese Methode wird von der
sendCommand()
-Methode der Hauptanwendungsdatei aufgerufen.
Anzeigen von Nachrichten vom Socketserver
Immer wenn eine Nachricht vom Socketserver empfangen wird oder ein Ereignis auftritt, wird die benutzerdefinierte
msg()
-Methode aufgerufen. Diese Methode fügt einen String an die TextArea-Komponente auf der Bühne an und ruft eine benutzerdefinierte
setScroll()
-Methode auf, die dafür sorgt, dass in der TextArea-Komponente ein Bildlauf bis zum Ende durchgeführt wird. Die
msg()
-Methode lautet folgendermaßen:
private function msg(value:String):void
{
ta.text += value;
setScroll();
}
Wenn Sie den Inhalt der TextArea-Komponente nicht automatisch scrollen, müssten die Benutzer die Bildlaufleisten im Textbereich manuell ziehen, um die letzte Antwort vom Server lesen zu können.
Durchführen eines Bildlaufs in einer TextArea-Komponente
Die
setScroll()
-Methode enthält eine einzelne ActionScript-Codezeile, mit der für den Inhalt der TextArea-Komponente ein vertikaler Bildlauf durchgeführt wird, sodass der Benutzer die letzte Zeile des zurückgegebenen Textes lesen kann. Die Methode
setScroll()
ist im folgenden Codeausschnitt dargestellt:
public function setScroll():void
{
ta.verticalScrollPosition = ta.maxVerticalScrollPosition;
}
Diese Methode stellt die Eigenschaft
verticalScrollPosition
ein, bei der es sich um die Zeilennummer der ersten angezeigten Zeichenreihe handelt, und stellt sie auf den Wert der Eigenschaft
maxVerticalScrollPosition
ein.
XML-Sockets
Mit XML-Sockets können Sie eine Verbindung mit einem Remoteserver erstellen. Die Verbindung bleibt so lange geöffnet, bis sie explizit geschlossen wird. Sie können Stringdaten, wie XML, zwischen Server und Client austauschen. Ein XML-Socketserver bietet den Vorteil, dass der Client die Daten nicht ausdrücklich anzufordern braucht. Der Server kann die Daten senden, ohne auf eine Anforderung warten zu müssen. Die Daten können an alle angeschlossenen Clients gesendet werden.
Für Flash Player und für Adobe AIR-Inhalt außerhalb der Anwendungs-Sandbox muss für XML-Socketverbindungen eine Socket-Richtliniendatei auf dem Zielserver vorhanden sein. Weitere Informationen finden Sie unter
Kontrolloptionen für Websites (Richtliniendateien)
und
Herstellen einer Verbindung mit Sockets
.
Die XMLSocket-Klasse kann nicht automatisch einen Tunnel durch Firewalls öffnen, da XMLSocket im Gegensatz zum RTMP-Protokoll (Real-Time Messaging Protocol) nicht über HTTP-Tunnelfähigkeiten verfügt. Wenn Sie HTTP-Tunneling verwenden müssen, sollten Sie die Verwendung von Flash Remoting oder Flash Mail Server in Betracht ziehen, da diese RTMP unterstützen.
Folgende Einschränkungen gelten bei Inhalt in Flash Player oder in einer AIR-Anwendung außerhalb der Sicherheits-Sandbox der Anwendung für die Herstellung einer Verbindung zwischen einem XMLSocket-Objekt und dem Server:
-
Bei Inhalt außerhalb der Sicherheits-Sandbox der Anwendung können mit der
XMLSocket.connect()
-Methode nur Verbindungen zu TCP-Portnummern größer oder gleich 1024 hergestellt werden. Als Folge dieser Einschränkung müssen den Serverdaemonprogrammen, die mit dem
XMLSocket
-Objekt kommunizieren, ebenfalls Portnummern größer oder gleich 1024 zugeordnet sein. Portnummern unter 1024 werden häufig von Systemdiensten wie FTP (21), Telnet (23), SMTP (25), HTTP (80) und POP3 (110) verwendet, und die Verwendung dieser Anschlüsse durch XMLSocket-Objekte ist aus Sicherheitsgründen nicht zulässig. Durch Einschränkung der verfügbaren Portnummern lässt sich das Risiko verringern, dass in ungeeigneter oder missbräuchlicher Weise auf diese Ressourcen zugegriffen wird.
-
Bei Inhalt außerhalb der Sicherheits-Sandbox der Anwendung können mit der
XMLSocket.connect()
-Methode nur Verbindungen zu Computern in derselben Domäne, in der sich der Inhalt befindet, hergestellt werden. (Diese Einschränkung ist identisch mit den Sicherheitsregeln für
URLLoader.load()
.) Wenn Sie eine Verbindung zu einem Serverdaemon herstellen möchten, der sich in einer anderen Domäne als der des Inhalts befindet, können Sie eine domänenübergreifende Richtliniendatei auf dem Server erstellen, mit dem der Zugriff von bestimmten Domänen möglich ist. Weitere Informationen zu domänenübergreifenden Richtliniendateien finden Sie unter
AIR-Sicherheit
.
Hinweis:
Die Einrichtung eines Servers zur Kommunikation mit einem XMLSocket-Objekt ist oft recht anspruchsvoll. Wenn Ihre Anwendung keine Interaktionen in Echtzeit erfordert, verwenden Sie die URLLoader-Klasse anstelle der XMLSocket-Klasse.
Mit den Methoden
XMLSocket.connect()
und
XMLSocket.send()
der XMLSocket-Klasse können Sie XML-Daten über eine Socketverbindung mit einem Server austauschen. Mit der Methode
XMLSocket.connect()
stellen Sie eine Socketverbindung zu einem Webserver-Port her. Mit der Methode
XMLSocket.send()
übergeben Sie ein XML-Objekt an den in der Socketverbindung festgelegten Server.
Wenn Sie die
XMLSocket.connect()
-Methode aufrufen, öffnet die Anwendung eine TCP/IP-Verbindung zum Server und erhält diese Verbindung aufrecht, bis eine der folgenden Bedingungen eintritt:
-
Die Methode
XMLSocket.close()
der XMLSocket-Klasse wird aufgerufen.
-
Es sind keine Verweise auf das XMLSocket-Objekt mehr vorhanden.
-
Flash Player wird beendet.
-
Die Verbindung wird unterbrochen (z. B. wenn die Modemverbindung getrennt wird).
Herstellen einer Serververbindung mit der XMLSocket-Klasse
Um eine Socketverbindung herzustellen, müssen Sie eine serverseitige Anwendung erstellen, die auf die Socketverbindungsanforderung wartet und eine Antwort an Flash Player oder die AIR-Anwendung sendet. Sie können diese serverseitige Anwendung in AIR oder in einer anderen Programmiersprache wie Java, Python oder Perl schreiben. Um die XMLSocket-Klasse verwenden zu können, muss auf dem Server ein Daemon ausgeführt werden, der das von der XMLSocket-Klasse verwendete einfache Protokoll verarbeiten kann:
-
XML-Nachrichten werden über eine TCP/IP-Streaming-Socketverbindung im Vollduplexmodus gesendet.
-
Jede XML-Nachricht ist ein vollständiges XML-Dokument, das mit einem Null-Byte (0) abgeschlossen wird.
-
Es kann eine unbegrenzte Anzahl von XML-Nachrichten über eine einzelne XMLSocketverbindung gesendet und empfangen werden.
Erstellen und Herstellen einer Verbindung mit einem Java XML-Socket-Server
Der folgende Code zeigt, wie ein einfacher XMLSocket-Server in Java geschrieben wird, der ankommende Verbindungen akzeptiert und die empfangenen Nachrichten in einem Fenster mit Eingabeaufforderung anzeigt. In der Standardeinstellung wird ein neuer Server am Port 8080 Ihres lokalen Computers erstellt. Sie können jedoch beim Starten des Servers von der Befehlszeile auch eine andere Portnummer angeben.
Erstellen Sie ein neues Textdokument und geben Sie den folgenden Code ein:
import java.io.*;
import java.net.*;
class SimpleServer
{
private static SimpleServer server;
ServerSocket socket;
Socket incoming;
BufferedReader readerIn;
PrintStream printOut;
public static void main(String[] args)
{
int port = 8080;
try
{
port = Integer.parseInt(args[0]);
}
catch (ArrayIndexOutOfBoundsException e)
{
// Catch exception and keep going.
}
server = new SimpleServer(port);
}
private SimpleServer(int port)
{
System.out.println(">> Starting SimpleServer");
try
{
socket = new ServerSocket(port);
incoming = socket.accept();
readerIn = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
printOut = new PrintStream(incoming.getOutputStream());
printOut.println("Enter EXIT to exit.\r");
out("Enter EXIT to exit.\r");
boolean done = false;
while (!done)
{
String str = readerIn.readLine();
if (str == null)
{
done = true;
}
else
{
out("Echo: " + str + "\r");
if(str.trim().equals("EXIT"))
{
done = true;
}
}
incoming.close();
}
}
catch (Exception e)
{
System.out.println(e);
}
}
private void out(String str)
{
printOut.println(str);
System.out.println(str);
}
}
Speichern Sie das Dokument „SimpleServer.java“ auf der Festplatte und kompilieren Sie es mithilfe eines Java-Compilers, der eine Java-Klassendatei namens „SimpleServer.class“ erstellt.
Sie können den XMLSocket-Server starten, indem Sie eine Eingabeaufforderung öffnen und
java SimpleServer
eingeben. Die Datei „SimpleServer.class“ kann sich in einem beliebigen Verzeichnis auf dem lokalen Computer oder im Netzwerk befinden; sie muss nicht im Hauptverzeichnis des Webservers angelegt sein.
Wenn Sie den Server nicht starten können, da sich die Dateien nicht im Java-Klassenpfad befinden, versuchen Sie, den Server mit
java -classpath . SimpleServer
zu starten.
Um von der Anwendung aus eine Verbindung mit der XMLSocket-Klasse herzustellen, müssen Sie eine neue Instanz der XMLSocket-Klasse erstellen und die
XMLSocket.connect()
-Methode aufrufen, der Sie Hostnamen und Portnummer wie folgt übergeben:
var xmlsock:XMLSocket = new XMLSocket();
xmlsock.connect("127.0.0.1", 8080);
Jedes Mal, wenn Sie Daten vom Server empfangen, wird das
data
-Ereignis (
flash.events.DataEvent.DATA
) ausgelöst:
xmlsock.addEventListener(DataEvent.DATA, onData);
private function onData(event:DataEvent):void
{
trace("[" + event.type + "] " + event.data);
}
Zum Senden von Daten an den XMLSocket-Server verwenden Sie die
XMLSocket.send()
-Methode und übergeben ein XML-Objekt oder einen String. Flash Player wandelt den angegebenen Parameter in ein String-Objekt um und sendet den Inhalt an den XMLSocket-Server, gefolgt von einem Null-Byte (0):
xmlsock.send(xmlFormattedData);
Die Methode
XMLSocket.send()
gibt keinen Wert zurück, der angibt, ob die Daten erfolgreich übermittelt wurden. Tritt bei dem Versuch, die Daten zu senden, ein Fehler auf, wird ein IOError-Fehler ausgelöst.
Jede Nachricht, die Sie an den XML-Socketserver senden, muss durch ein Zeilenvorschubzeichen (
\n
) beendet werden.
Weitere Informationen finden Sie unter
XMLSocket
.
Serversockets
Mithilfe der ServerSocket-Klasse geben Sie anderen Prozessen die Möglichkeit, über ein TCP-Socket (Transport Control Protocol) eine Verbindung mit Ihrer Anwendung herzustellen. Der Verbindungsprozess kann auf dem lokalen Computer oder auf einem anderen Computer im Netzwerk ausgeführt werden. Wenn ein ServerSocket-Objekt eine Verbindungsanforderung erhält, löst es ein
connect
-Ereignis aus. Das mit dem Ereignis ausgelöste ServerSocketConnectEvent-Objekt enthält ein Socket-Objekt. Dieses Socket-Objekt kann für die weitere Kommunikation mit dem anderen Prozess verwendet werden.
So warten Sie auf eingehende Socketverbindungen:
-
Erstellen Sie ein ServerSocket-Objekt und binden Sie es an einen lokalen Port.
-
Fügen Sie Ereignis-Listener für das
connect
-Ereignis hinzu.
-
Rufen Sie die
listen()
-Methode auf.
-
Reagieren Sie auf das
connect
-Ereignis, das ein Socket-Objekt für jede eingehende Verbindung bereitstellt.
Das ServerSocket-Objekt wartet auf neue Verbindungen, bis Sie die
close()
-Methode aufrufen.
Das folgende Codebeispiel veranschaulicht die Erstellung einer Socket-Serveranwendung. Im Beispiel wird an Port 8087 auf eingehende Verbindungen gewartet. Wenn eine Verbindung empfangen wird, sendet das Beispiel eine Nachricht (den String „Connected“) an das Clientsocket. Anschließend gibt der Server empfangene Nachrichten per Echo an den Client zurück.
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.ServerSocketConnectEvent;
import flash.net.ServerSocket;
import flash.net.Socket;
public class ServerSocketExample extends Sprite
{
private var serverSocket:ServerSocket;
private var clientSockets:Array = new Array();
public function ServerSocketExample()
{
try
{
// Create the server socket
serverSocket = new ServerSocket();
// Add the event listener
serverSocket.addEventListener( Event.CONNECT, connectHandler );
serverSocket.addEventListener( Event.CLOSE, onClose );
// Bind to local port 8087
serverSocket.bind( 8087, "127.0.0.1" );
// Listen for connections
serverSocket.listen();
trace( "Listening on " + serverSocket.localPort );
}
catch(e:SecurityError)
{
trace(e);
}
}
public function connectHandler(event:ServerSocketConnectEvent):void
{
//The socket is provided by the event object
var socket:Socket = event.socket as Socket;
clientSockets.push( socket );
socket.addEventListener( ProgressEvent.SOCKET_DATA, socketDataHandler);
socket.addEventListener( Event.CLOSE, onClientClose );
socket.addEventListener( IOErrorEvent.IO_ERROR, onIOError );
//Send a connect message
socket.writeUTFBytes("Connected.");
socket.flush();
trace( "Sending connect message" );
}
public function socketDataHandler(event:ProgressEvent):void
{
var socket:Socket = event.target as Socket
//Read the message from the socket
var message:String = socket.readUTFBytes( socket.bytesAvailable );
trace( "Received: " + message);
// Echo the received message back to the sender
message = "Echo -- " + message;
socket.writeUTFBytes( message );
socket.flush();
trace( "Sending: " + message );
}
private function onClientClose( event:Event ):void
{
trace( "Connection to client closed." );
//Should also remove from clientSockets array...
}
private function onIOError( errorEvent:IOErrorEvent ):void
{
trace( "IOError: " + errorEvent.text );
}
private function onClose( event:Event ):void
{
trace( "Server socket closed by OS." );
}
}}
Weitere Informationen finden Sie unter:
UDP-Sockets (AIR)
Das UDP-Protokoll (Universal Datagram Protocol) bietet die Möglichkeit, Nachrichten über eine Stateless-Netzwerkverbindung auszutauschen. Bei UDP besteht keine Garantie, dass Nachrichten zugestellt oder in der richtigen Reihenfolge zugestellt werden. Bei Verwendung von UDP wendet der Netzwerkcode des Betriebssystems meist weniger Zeit für Überwachung, Verfolgung und Bestätigung der Nachrichten auf. Deshalb gehen UDP-Nachrichten in der Regel mit einer kürzeren Verzögerung bei der Zielanwendung ein, als dies bei TCP-Nachrichten der Fall ist.
Die UDP-Socketkommunikation eignet sich gut zum Senden von Echtzeitinformationen, beispielsweise Positionsaktualisierungen in einem Spiel oder Soundpakete in einer Chat-Anwendung mit Audiofunktion. In solchen Anwendungen ist ein gewisses Maß an Datenverlust hinnehmbar, da eine niedrigere Übertragungslatenz wichtiger ist als die garantierte Nachrichtenzustellung. Für fast alle anderen Zwecke sind TCP-Sockets besser geeignet.
AIR-Anwendungen können UDP-Nachrichten über die DatagramSocket- und DatagramSocketDataEvent-Klassen senden und empfangen. So senden oder empfangen Sie eine UDP-Nachricht:
-
Erstellen Sie ein DatagramSocket-Objekt.
-
Fügen Sie einen Ereignis-Listener für das
data
-Ereignis hinzu.
-
Binden Sie das Socket mithilfe der
bind()
-Methode an eine lokale IP-Adresse und einen lokalen Port.
-
Senden Sie Nachrichten durch Aufruf der
send()
-Methode, wobei die IP-Adresse und der Port des Zielcomputers übergeben werden müssen.
-
Empfangen Sie Nachrichten durch Reagieren auf das
data
-Ereignis. Das für dieses Ereignis ausgelöste DatagramSocketDataEvent-Objekt enthält ein ByteArray-Objekt, das wiederum die Nachrichtendaten enthält.
Im folgenden Codebeispiel wird veranschaulicht, wie eine Anwendung UDP-Nachrichten senden und empfangen kann. Das Beispiel sendet eine einzelne Nachricht mit dem String „Hello.“ an den Zielcomputer. Außerdem wird der Inhalt der empfangenen Nachrichten verfolgt.
package
{
import flash.display.Sprite;
import flash.events.DatagramSocketDataEvent;
import flash.events.Event;
import flash.net.DatagramSocket;
import flash.utils.ByteArray;
public class DatagramSocketExample extends Sprite
{
private var datagramSocket:DatagramSocket;
//The IP and port for this computer
private var localIP:String = "192.168.0.1";
private var localPort:int = 55555;
//The IP and port for the target computer
private var targetIP:String = "192.168.0.2";
private var targetPort:int = 55555;
public function DatagramSocketExample()
{
//Create the socket
datagramSocket = new DatagramSocket();
datagramSocket.addEventListener( DatagramSocketDataEvent.DATA, dataReceived );
//Bind the socket to the local network interface and port
datagramSocket.bind( localPort, localIP );
//Listen for incoming datagrams
datagramSocket.receive();
//Create a message in a ByteArray
var data:ByteArray = new ByteArray();
data.writeUTFBytes("Hello.");
//Send the datagram message
datagramSocket.send( data, 0, 0, targetIP, targetPort);
}
private function dataReceived( event:DatagramSocketDataEvent ):void
{
//Read the data from the datagram
trace("Received from " + event.srcAddress + ":" + event.srcPort + "> " +
event.data.readUTFBytes( event.data.bytesAvailable ) );
}
}}
Berücksichtigen Sie bei Verwendung von UDP-Sockets die folgenden Punkte:
-
Ein einzelnes Datenpaket kann nicht größer sein als die kleinste maximale Übertragungseinheit der Netzwerkschnittstelle oder eines Netzwerkknotens zwischen dem Sender und dem Empfänger. Alle Daten im ByteArray-Objekt, das an die send()-Methode übergeben wird, werden als einzelnes Paket gesendet. (Bei TCP werden umfangreiche Nachrichten in separate Pakete aufgeteilt.)
-
Es erfolgt kein Handshaking zwischen Sender und Ziel. Wenn das Ziel nicht existiert oder keinen aktiven Listener am angegebenen Port hat, werden Nachrichten ohne Fehler verworfen.
-
Bei Verwendung der
connect()
-Methode werden Nachrichten, die von anderen Quellen gesendet werden, ignoriert. Eine UDP-Verbindung bietet lediglich eine praktische Paketfilterung. Es ist nicht gewährleistet, dass sich an der Zieladresse und am Zielport ein gültiger Prozess befindet, der auf die Nachricht wartet.
-
UDP-Datenverkehr kann zu einer Überbelastung des Netzwerks führen. Bei einer zu hohen Netzwerkbeanspruchung müssen Netzwerkadministratoren möglicherweise QoS-Steuerungen implementieren. (TCP verfügt über integrierte Datenverkehrssteuerungen, um die Belastung des Netzwerks zu verringern.)
Weitere Informationen finden Sie unter:
IPv6-Adressen
IPv6 (Internet Protocol Version 6) wird ab Flash Player 9.0.115.0 unterstützt. IPv6 ist eine Internet Protocol-Version, die 128-Bit-Adressen unterstützt (eine Verbesserung gegenüber der älteren Version IPv4, die 32-Bit-Adressen unterstützt). Möglicherweise müssen Sie IPv6 für Ihre Netzwerkschnittstellen aktivieren. Weitere Informationen finden Sie in der Hilfe des Betriebssystems, unter dem die Daten gehostet werden.
Wenn IPv6 vom Hostingsystem unterstützt wird, können Sie in URLs numerische IPv6-Literaladressen in eckigen Klammern angeben, wie im folgenden Beispiel:
[2001:db8:ccc3:ffff:0:444d:555e:666f]
Flash Player gibt IPv6-Literaladressen entsprechende der folgenden Regeln zurück:
-
Flash Player gibt die den String der IPv6-Adresse in der Langform zurück.
-
Der IP-Wert weist keine Abkürzungen mit doppeltem Doppelpunkt auf.
-
Hexadezimalwerte sind immer nur in Kleinschreibung.
-
IPv6-Adressen sind in eckigen Klammern eingeschlossen.
-
Jedes Adressquartett wird in Form von 0 bis 4 Hexadezimalwerten ausgegeben, wobei die führenden Nullen ausgelassen werden.
-
Ein aus Nullen bestehendes Adressquartett wird als einzelne Null ausgegeben (nicht als doppelter Doppelpunkt); die Ausnahmen können Sie der folgenden Liste entnehmen.
Die von Flash Player zurückgegebenen IPv6-Werte weisen die folgenden Ausnahmen auf:
-
Eine nicht angegebene IPv6-Adresse (ausschließlich Nullen) wird als [::] ausgegeben.
-
Die Loopback- oder Localhost-IPv6-Adresse wird als [::1] ausgegeben.
-
IPv4-zugeordnete Adressen (in IPv6 umgewandelt) werden als [::ffff:a.b.c.d] ausgegeben, wobei es sich bei „a.b.c.d“ um einen typischen Punktdezimalwert von IPv4 handelt.
-
IPv4-kompatible Adressen werden als [::a.b.c.d] ausgegeben, wobei es sich bei „a.b.c.d“ um einen typischen Punktdezimalwert von IPv4 handelt.
|
|
|
|
|