-Aussage, halten Sie sich von den hirntoten Menschen fern. Der Kern dieses Blogs ist nicht das IF-ELSE+ -Präfix, sondern wie man ein privates Protokoll im Rahmen des URL-Protokollverarbeitungsgerüsts definiert
Der Unterschied zwischen einem URI und einer URL
URI (Uniform Resource Identifier) Einheitliche Ressourcenkennung; URL (Einheitlicher Ressourcenort) einheitlicher Ressourcenlocator (oder einheitlicher Ressourcenlocator); URI ist ein relativ breites Konzept. URL ist eine Art URI und eine Untergruppe des URI -Namensmechanismus. Es kann gesagt werden, dass URI abstrakt ist und die spezifische Verwendung von URLs zur Lokalisierung von Ressourcen. Die URI weist im Allgemeinen nicht auf den physischen Ressourcenpfad, sondern auf den kartierten Ressourcenkennung im gesamten System hin. URLs sind im Internet verwendet, um Informationsressourcen zu beschreiben, die hauptsächlich für verschiedene WWW -Client -Programme und Serverprogramme verwendet werden. Die Verwendung von URLs kann ein einheitliches Format verwenden, um verschiedene Informationsressourcen zu beschreiben, einschließlich Dateien, Serveradressen und Verzeichnissen usw.
1. Lassen Sie uns zunächst vor dem Vorwort
Wir sind an http gewohnt
URL URL = New URL (http://www.apptest.com:8080/test/ios.php);
Wir müssen uns auch daran gewöhnen
Natürlich müssen wir uns auch an die URL gewöhnen.
"https", "ftp", "mailto", "telnet", "file", "ldap", "gopher", "jdbc", "rmi", "jndi", "jar", "doc", "netdoc", "nfs", "verbatim", "finger"
URL URL = New URL ("Oschina: //www.apptest.com: 8080/test/ios.php");Wenn Sie nicht daran gewöhnt sind, treten die folgenden Ausnahmen immer auf
Java.net.Malformedurlexception: Unbekanntes Protokoll
Bei Verwendung von AJAX in Android -Browsern werden undefinierte Protokolle nicht unterstützt.
2. Verständnis von benutzerdefinierten Protokollen
Protokoll: In der Programmierwelt ist das Protokoll selbst eine Reihe von Eingabe-/Ouput -Einschränkungsregeln. Daher sollte sich unser genaues Protokoll um E/A drehen, sodass das Protokoll hier als E/A -Protokoll bezeichnet werden kann.
Vereinbarungsinitiator: Anfrage
Protokollempfänger: Antwort
Die Bedingungen für die Einrichtung der Vereinbarung sind: Anfrage und Antwort erkennen dieselben Vereinbarungen an und kommunizieren gemäß den Einschränkungen der Vereinbarung.
3. Die Beziehung zwischen benutzerdefiniertem Protokoll und URL
Benötigen Sie in Java kundenspezifische Protokolle URLs?
Die Antwort ist nein.
In der Tat sind unsere Regeldefinitionen um I/O vollständig in den eigenen Händen. Es heißt nicht, dass sich die Erde nach dem Verlassen der URL nicht umdrehen wird und Java zerstört wird.
Warum das Protokoll mit URL -Klassen anpassen?
Die Antwort ist, dass URL ein ausgereiftes Rahmen für die Verarbeitungsverarbeitungsverarbeitungsverarbeitungsverarbeitungszeit für Protokoll ist.
Das hier erwähnte benutzerdefinierte URL -Protokoll geht es im Wesentlichen mehr um die Erweiterung des Protokolls durch bestehende Regeln.
4. URL Custom Private Protocol Practice
Wir wissen, dass benutzerdefinierte Protokolle Antwort und Anfrage erfordern, und beide Parteien müssen die Vereinbarung des anderen vollständig verstehen. Zur Bequemlichkeit hier verwenden wir den HTTP -Protokollserver als Antwort.
Hier verwenden wir NGNIX Server + PHP + FastCGI, um die Antwort zu erstellen, und der Bereitstellungscode lautet wie folgt
1. Definieren Sie die Antwort
<? php $ raw_post_data = file_get_contents ('php: // input', 'r'); echo "-------/$ _ post ------------------/n <br/>"; echo var_dump ($ _ post). "/N"; echo "------- php: // Eingabe -------------/n <br/>"; echo $ raw_post_data. "/n <br/>"; $ rs = json_encode ($ _ server); file_put_contents ('text.html', $ rs); echo '写入成功';2. Definieren Sie die Anfrage
2.1 Implementierung der UrlstreamHandlerFactory -Fabrik, die hauptsächlich zur Generierung von Protokollprozessoren verwendet wird
öffentliche Klasse EchourLStreamHandlerFactory implementiert urlstreamHandlerfaktorisch {public urlstreamHandler createurlstreamHandler (String -Protokoll) {// Anpassen verschiedener Schemaanfragen durch die Umleitung. Natürlich denken die hirntoten Leute, dass dies der Kerncode ist. URL ist ein Protokollverarbeitungsrahmen. Wenn If-ELSE der Kern ist, wird Oracle bankrott sein, wenn (protocol.equals ("echo") || protocol.equals ("oschina") {neue echourlstreamHandler () zurückgeben; // den Protokollverarbeitungs -Handler instanziieren} return null; }}2.2 Implementieren von UrlstreamHandler besteht die Hauptfunktion darin, den entsprechenden Stecker des Protokolls zu erzeugen
public class EchourlstreamHandler erweitert UrlStreamHandler {@OverrideProtected urlConnection openConnection (url u) löscht ioException {return New EchourlConnection (u); // Wir können hier auch die entsprechende Umleitung durchführen}} 2.3 URLCONNECTION implementieren, bei der die Anpassung der Protokollkommunikationsregeln angewendet wird. Hier verwenden wir das HTTP -Protokoll als Kommunikationsregeln. Hier imitieren wir HTTP -Protokollanfragen
(Das Folgende ist der Kerncode. Das hier geliehene HTTP-Protokoll. Natürlich können Sie mit verschiedenen Protokollen mit WebSocket, SMTP und FTP mit verschiedenen Protokollen interagieren, anstatt das IF-ELSE+URL-Präfix, das mich für hirntägliche Menschen zugeben, um zuzugeben )
öffentliche Klasse EchourlConnection erweitert die UrlConnection {private Socket Connection = null; public Final static int default_port = 80; public echourlConnection (url url) {super (url);} public synchronisierte InputStream getInputStream () veröffentlichen ioException {! OutputStream -GetOutputStream () löscht IOException {if (! Anschließend) {Connect ();} return Connection.getOutputStream ();} public String getContentType () {return "text/plain"} public synchronized void connect () löst iOException {if (! CONNECTED). 65535) port = default_port; this.connection = neuer Socket (url.gethost (), port); // true Mittel zum Ausschalten der Pufferung des Sockets und sofort Daten zu senden. Der Standardwert ist falsch // Wenn die zugrunde liegende Implementierung von Socket die tcp_nodelay -Option nicht unterstützt. this.connection.setReuseaddress (true); // Zeigt das Wartezeitübergang an, wenn Daten in Millisekunden empfangen werden. Um die Daten erneut zu lesen. Nach 5 Sekunden werden alle verbleibenden Daten, die nicht gesendet wurden, verworfen. Wenn die Methode von Socket.close () ausgeführt wird, kehrt die Methode standardmäßig sofort zurück, aber der zugrunde liegende Socket wird nicht sofort geschlossen // Es verzögert sich über einen bestimmten Zeitraum, bis alle verbleibenden Daten gesendet werden, und der Socket wird wirklich geschlossen und getrennt // Tipps: Wenn das Programm "Daten zu dem Programm" verantwortlich ist. Das Programm wird nur verantwortlich gemacht. Tipps: Wenn das Programm den Socket schließt, ist es möglich, dass die Datenstapel immer noch im Netzwerk übertragen wird und den Empfänger nicht erreicht hat // Tipps: Die hier erwähnten "verbleibenden Daten" bezieht sich auf diese Daten, die immer noch im Netzwerk übertragen wurden und nicht von der Empfänger empfangen wurden. Konnection.SetSolinger (true 5). this.connection.setsendBufferSize (1024); // zeigt die Größe des Puffer an, in dem die Daten empfangen werden. Daten nicht aneinander übertragen)? TRUE ist Ja // sein Standardwert ist falsch, was bedeutet, dass TCP nicht überwacht, ob die Verbindung gültig ist, und inaktive Clients dauerhaft ohne Beachten Sie, dass der Server dies abgestürzt hat. // gibt an, ob es unterstützt, ein Byte von TCP -Notfalldaten zu senden. Socket.SendurgentData (Daten) wird verwendet, um ein Byte von TCP -Notfalldaten zu senden // Es wird standardmäßig an False gesendet, dh der Empfänger führt keine Verarbeitung durch, wenn die Notfalldaten empfangen werden und sie direkt abfällt. Wenn der Benutzer Notfalldaten senden möchte, sollte er auf true // nach der Einstellung auf true eingestellt werden. Der Empfänger stellt die empfangenen Notfalldaten in dieselbe Warteschlange wie die normalen Daten. Der folgende Code fordert eine hohe Zuverlässigkeits- und Mindestverzögerungsübertragungsdienst an (Bits oder Operationen von 0x04 und 0x10) // Socket -Klasse verwendet 4 Ganzzahlen, um den Servicetyp zu repräsentieren // 0x02: kostengünstiges (das vorletzte Bit von Binary ist 1). 0x10: Mindestverzögerung (das fünfte vorletzte Bit von Binärdien ist 1) Diese. latency-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- url.getPath () + "http/1.1 /r/n");/if(url.getport()<0 || url.getport ()> 65536) {sb.append ("host:"). append (url.gethost ()). append ("/r/n");} else {sb.append ("host:"). append (url.get Host ()). Append (":"). Append (url.getport ()). Append ("/r/n");} sb.append ("Verbindung: Keep-Alive/R/N"); 22. April 2016 13:17:35 GMT/R/N "); ") .Append (" name = zhangsan & password = 123456 ".getBytes (" utf-8 "). Länge) .And ("/r/n "); Disconnect () löst ioException {if (verbunden) {this.connection.close (); this.connected = false;}}} aus Hier wurde die Protokolldefinition abgeschlossen.
Unser Testcode ist wie folgt
Versuchen Sie, eine Verbindung zu Oschina: // localhost: 8080/test/ios.php herzustellen
Url.seturlstreamHandlerfactory (new echourlstreamHandlerfactory ()); // urlConnection.setContentHandlerfactory (New EchocontentHandlerfactory ()); url url = new url ("oschina: // localhost: 8080/test/ios.php"); connection = (echourlConnection) url.openconnection (); connection.setDooutput (true); connection.setDoInput (true); Pressewriter PW = neuer Pressewriter (neuer Ausgangsstreamwriter (connection.getOutputStream ()); InputStream stream = connection.getInputStream (); int len = -1; byte [] buf = neues byte [256]; while ((len = stream.read (buf, 0, 256))>-1) {String line = new String (buf, 0, len); if (line.endswith ("/r/n0/r/r/r/n") && len <256) {// Der Server gibt eine Codierung von Transfer-Chunk-Codierung zurück,/r/n0/r/n/r/n line.length ()-"/r/n0/r/n/r/n" .Length ()); System.out.println (Linie); brechen; } else {System.out.println (Zeile); }} pw.close (); stream.close ();Auslaufergebnisse
Das Ergebnis zeigt, dass das Protokoll tatsächlich erfolgreich definiert wurde
Natürlich entspricht die obige Datenanalyse unsere Anforderungen nicht, da es sich um eine Chunked -Codierungsinformationen handelt. So analysieren Sie es erfüllt die Anforderungen. Bitte bewegen Sie sich :
HTTP -Chunked -Datencodierung und Parsing -Algorithmus
5. Später, benutzerdefinierter Minetyp -Parser
ContentHandlerFactory wird in Java bereitgestellt, um den Minetyp zu analysieren. Wir formulieren hier unseren eigenen Parser. Natürlich sorgt der JDK reichlicher. Was wir hier tun, ist, besondere Bedürfnisse zu erfüllen.
public class EchocontentHandler erweitert ContentHandler {public Object getContent (UrlConnection Connection). {InputStream in = connection.getInputStream (); für (int i = 0; i <classes.length; i ++) {if (classes [i] == inputStream.class) return in; else if (classes [i] == string.class) return getContent (connection);} return null;}}}}}}}}}}}}}}}}}}}}}}}};Die Verwendung ist sehr einfach
UrlConnection.setContentHandlerFactory (neuer echocontentHandlerfactory ());