-Pernyataan, Jauhkan dari orang-orang yang mati. Inti dari blog ini bukan awalan IF-Else+, tetapi bagaimana mendefinisikan protokol pribadi melalui kerangka pemrosesan protokol URL
Perbedaan antara URI dan URL
URI (Pengidentifikasi Sumber Daya Seragam) Pengidentifikasi Sumber Daya Seragam; URL (Lokasi Sumber Daya Seragam) Locator Sumber Daya Seragam (atau Locator Sumber Daya Terpadu); URI adalah konsep yang relatif luas. URL adalah jenis URI dan subset dari mekanisme penamaan URI. Dapat dikatakan bahwa URI abstrak, dan penggunaan URL khusus untuk menemukan sumber daya. URI umumnya menunjuk ke jalur sumber daya fisik, tetapi pengidentifikasi sumber daya yang dipetakan di seluruh sistem. URL adalah string yang digunakan di Internet untuk menggambarkan sumber daya informasi, terutama digunakan pada berbagai program klien WWW dan program server. Menggunakan URL dapat menggunakan format terpadu untuk menggambarkan berbagai sumber informasi, termasuk file, alamat server dan direktori, dll.
1. Ayo Kata Pengantar
Kami sudah terbiasa dengan http
Url url = url baru (http://www.apptest.com:8080/test/ios.php);
Kita juga harus terbiasa dengan itu
Tentu saja, kita juga perlu terbiasa dengan URL.
"https", "ftp", "mailto", "Telnet", "file", "ldap", "gopher", "jdbc", "rmi", "jndi", "jar", "doc", "netdoc", "nfs", "verbatim", "finger" "day day", "nfs", "verbatim", "finger" day day umber "," nfs "," verbatim "," finger "day day umbe", "nfs", "verbatim", "finger" day day umber "," nfs "," vERBATIM "," finger "DAGU -DAGU -DARI"
Url url = url baru ("oschina: //www.apptest.com: 8080/test/ios.php");Jika Anda tidak terbiasa, pengecualian berikut akan selalu terjadi
java.net.malformedurlexception: protokol yang tidak diketahui
Saat menggunakan AJAX di browser Android, protokol yang tidak ditentukan tidak akan didukung.
2. Pemahaman Protokol Kustom
Protokol: Di dunia pemrograman, protokol itu sendiri adalah seperangkat aturan kendala input/ouput. Oleh karena itu, protokol yang tepat kita harus berputar di sekitar I/O, sehingga protokol di sini dapat disebut protokol I/O.
Inisiator Perjanjian: Permintaan
Protokol Responder: Respons
Ketentuan untuk pembentukan perjanjian adalah: Permintaan dan Respons Mengenali rangkaian perjanjian yang sama dan berkomunikasi sesuai dengan kendala perjanjian.
3. Hubungan antara protokol khusus dan URL
Di Java, apakah protokol khusus memerlukan URL?
Jawabannya adalah tidak.
Bahkan, sekitar I/O, definisi aturan kita sepenuhnya ada di tangan kita sendiri. Tidak mengatakan bahwa bumi tidak akan berbalik setelah meninggalkan URL, dan Jawa akan dihancurkan.
Mengapa menyesuaikan protokol menggunakan kelas URL?
Jawabannya adalah karena URL adalah kerangka pemrosesan komunikasi protokol yang matang.
Protokol URL khusus yang disebutkan di sini pada dasarnya lebih banyak tentang memperluas protokol melalui aturan yang ada.
4. URL Praktik Protokol Pribadi Kustom
Kami tahu bahwa protokol khusus memerlukan respons dan permintaan, dan kedua belah pihak perlu sepenuhnya memahami perjanjian satu sama lain. Untuk kenyamanan di sini, kami menggunakan server HTTP Protocol sebagai respons.
Di sini kami menggunakan NGNIX Server + PHP + FastCGI untuk membangun tanggapan, dan kode penyebaran adalah sebagai berikut
1. Tentukan respons
<? php $ raw_post_data = file_get_contents ('php: // input', 'r'); echo "-------/$ _ posting ------------------/n <br/>"; echo var_dump ($ _ post). "/N"; echo "------- php: // input -------------/n <br/>"; echo $ raw_post_data. "/n <br/>"; $ rs = json_encode ($ _ server); file_put_contents ('text.html', $ rs); echo '写入成功';2. Tentukan permintaan
2.1 Menerapkan pabrik UrlStreamHandlerFactory, terutama digunakan untuk menghasilkan prosesor protokol
Kelas Publik EchourlStreamHandlerFactory mengimplementasikan URLStreamHandlerFactory {UrlStreamHandler Public CreateUrlStreamHandler (String Protocol) {// Sesuaikan permintaan skema yang berbeda melalui pengalihan di sini. Tentu saja, orang yang mati otak berpikir bahwa ini adalah kode inti. URL adalah kerangka pemrosesan protokol. Jika if-else adalah intinya, apakah Oracle akan bangkrut jika (protocol.equals ("echo") || protocol.equals ("oschina")) {return echourlStreamHandler () baru; // instantiate handler pemrosesan protokol} return null; }}2.2 Menerapkan UrlStreamHandler, fungsi utamanya adalah untuk menghasilkan konektor protokol yang sesuai
Kelas Publik EchourlStreamHandler memperluas URLStreamHandler {@Overrideprotected urlconnection openconnection (url u) melempar ioException {return echourlconnection baru (u); // kita juga dapat melakukan pengalihan yang sesuai di sini}} 2.3 Menerapkan UrlConnection, yang merupakan penyesuaian aturan komunikasi protokol. Di sini kami menggunakan protokol HTTP sebagai aturan komunikasi. Di sini kami meniru permintaan protokol HTTP
(Berikut ini adalah kode inti. Protokol HTTP dipinjam di sini. Tentu saja, Anda dapat berinteraksi dengan berbagai protokol menggunakan WebSocket, SMTP, dan FTP, alih-alih awalan URL IF-Else+yang diminta oleh orang yang mati otak ))
Kelas publik EchourlConnection memperluas urlconnection {private socket connection = null; public final static int default_port = 80; public echourlconnection (url url) {super (url);} public sinchronized inputStream getInputStream () throws ioException {if (! connected) {if (! OutputStream getOutputStream () melempar ioException {if (! Connected) {connect ();} return connection.getOutputStream ();} public string getContentType () {return "text/polos";} port portport () portport () portport () ife () {if (! 65535) port = default_port; this.connection = soket baru (url.gethost (), port); // berarti benar untuk mematikan buffering soket dan mengirim data segera .. nilai defaultnya salah // Jika implementasi yang mendasari soket tidak mendukung opsi tcp_nodelay, socketExceptionThis.connection.settcpnodelay (socketExcepteSception.connection.settcpnodelay (socketExcepteSeSe.connection.settcpnodelay (socketExcepteSteSe.concection.settcpnodelay (socketExcepteSeSeUse.connection.settcpnodely Option (socketExceptionseTheuse.connection.settcpnodelay (socketExceptate.connecties. this.connection.setReuseAddress(true);// Indicates the waiting timeout when receiving data, in milliseconds.. The default value is 0, which means that there will be infinite waiting and will never timeout// When reading data through the Socket input stream, if there is no data, it will wait// After the timeout, the SocketTimeoutException will be thrown, and after the exception is thrown, the Socket is still connected, you can Cobalah untuk membaca data ini lagi. Setelah 5 detik, semua data yang tersisa yang belum dikirim akan dibuang. Secara default, jika metode soket.close () dieksekusi, metode ini akan segera kembali, tetapi soket yang mendasarinya sebenarnya tidak ditutup segera // Ini akan menunda untuk periode waktu sampai semua data yang tersisa dikirim, dan soket akan benar -benar ditutup dan diputuskan // Kiat: ketika program menulis data melalui aliran output, itu hanya berarti bahwa program tersebut mengirimkan kumpulan dari kumpulan. Kiat: Ketika program menutup soket, ada kemungkinan bahwa batch data masih ditransmisikan pada jaringan dan belum mencapai penerima // tips: "data yang tersisa" yang disebutkan di sini mengacu pada data ini yang masih ditransmisikan pada jaringan dan belum diterima oleh penerima ini. this.connection.setsendBufferSize (1024); // menunjukkan ukuran buffer di mana data diterima ini. tidak mengirimkan data satu sama lain)? Benar adalah ya // Nilai defaultnya salah, yang berarti bahwa TCP tidak akan memantau apakah koneksi valid, dan klien yang tidak aktif mungkin ada secara permanen tanpa pemberitahuan bahwa server telah merusak ini.connection.setkeepalive (true); // menunjukkan apakah mendukung pengiriman satu byte data darurat TCP. Socket.SendurgentData (data) digunakan untuk mengirim satu byte data darurat TCP // default ke false, yaitu, penerima tidak melakukan pemrosesan saat menerima data darurat dan secara langsung membuangnya. Jika pengguna ingin mengirim data darurat, itu harus diatur ke true // setelah ditetapkan ke true, penerima akan menempatkan data darurat yang diterima dalam antrian yang sama dengan data normal this.connection.setoobinline (true); // Metode ini digunakan untuk mengatur jenis layanan. Kode berikut meminta layanan transmisi keandalan tinggi dan penundaan minimum (bit atau operasi 0x04 dan 0x10) // Socket Class menggunakan 4 bilangan bulat untuk mewakili jenis layanan // 0x02: biaya rendah (bit biner 1) // 0x04: Keandalan tinggi (Bit Bit Biting Biting 1) // 0x04: The Bit Bit 1). 0x10: Penundaan minimum (bit biner kedua adalah 1) this.connection.settrafficclass (0x04 | 0x10); // Metode ini digunakan untuk mengatur kepentingan relatif waktu koneksi, penundaan, dan bandwidth (tiga parameter dari metode ini mewakili tiga indikator data transmisi jaringan) // Param Paramy-Mearer Mearer A Measing A Measing Meperping Acnection Dengan Tiga Indikator Data Transmisi Jaringan) // Koneksi-Param Paramy-This Measing MeaRETER MATERI AREKSIVE MENJADI Tiga Indikator Jaringan Data Transmisi Jaringan)//Bandwidth-This Measing Mearer Mata 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 ("Koneksi: Keep-Alive/r/n"); SB.Append ("Tanggal: Jum, 22 Apr 2016 13:17:35 GMT/r/n");sb.append("Vary:Accept-Encoding/r/n");sb.append("Content-Type: application/x-www-form-urlencoded,charset=utf-8/r/n");sb.append("Content-Length: ") .Append (" Name = Zhangsan & Password = 123456 ".getBytes (" UTF-8 "). Length) .Append ("/r/n "); SB.Append ("/r/n "); ini Disconnect () melempar ioException {if (terhubung) {this.connection.close (); this.connected = false;}}} Di sini, definisi protokol telah selesai.
Kode tes kami adalah sebagai berikut
Coba hubungkan ke oschina: // localhost: 8080/test/ios.php
Url.setUrlStreamHandlerFactory (echourlStreamHandlerFactory baru ()); // urlconnection.setContenthandlerFactory (echocontenthandlerfactory () baru () URL = oschina: // localhost: 8080/uji/ios.php "; Oschina: // localhost: 8080/uji/ios.php"); Oschina: oschina: // localhost: 8080/uji/ios.php "); OSCHP"; OSCHP "; oschina; koneksi = (echourlconnection) url.openconnection (); connection.setDoOutput (true); connection.setDoInput (true); Printwriter pw = printwriter baru (outputStreamWriter baru (connection.getoutputStream ())); pw.write ("name = zhangsan & kata sandi = 123456"); pw.flush (); InputStream stream = connection.getInputStream (); int len = -1; byte [] buf = byte baru [256]; while ((len = stream.read (buf, 0, 256))>-1) {string line = string baru (buf, 0, len); if (line.endswith ("/r/n0/r/n/r/n") && len <256) {// Server mengembalikan pengkodean yang ditransfer,/r/n0/r/n/r/n berarti bahwa pembacaan telah berakhir, analisis encoding yang dikupas: http:/dbsccx.iteee.com, http: http:/dbsccx.iteee.com/drunye.com/sblog/sblog/http: http:.dbsccx.iteEe.com/drunye.com/drunye.com/sblog/sblog/http: http:/dbsccx.itee.com, http: http:/dbsccx.itee.com/drunye.com/drunye.com/drunye.com/drunye.com/drunye.com/http: http:/dbscx.itee.com, http: line.length ()-"/r/n0/r/n/r/n" .length ()); System.out.println (baris); merusak; } else {System.out.println (line); }} pw.close (); stream.close ();Hasil berjalan
Hasilnya menunjukkan bahwa protokol memang telah didefinisikan dengan sukses
Tentu saja, analisis data di atas tidak memenuhi persyaratan kami karena itu adalah informasi pengkodean yang dipotong. Cara menganalisisnya memenuhi persyaratan, silakan pindahkan :
HTTP Pengkodean Data Pengkodean dan Parsing Algoritma
5. nanti, parser minetype khusus
ContentHandlerFactory disediakan di Java untuk parse minetype. Kami merumuskan parser kami sendiri di sini. Tentu saja, JDK menyediakan lebih banyak. Apa yang kami lakukan di sini adalah memenuhi kebutuhan khusus.
public class EchoContentHandler extends ContentHandler {public Object getContent(URLConnection connection) throws IOException {InputStream in = connection.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(in));return br.readLine();}public Object getContent(URLConnection connection, Class[] classes) throws IoException {inputStream in = connection.getInputStream (); for (int i = 0; i <class.length; i ++) {if (class [i] == inputStream.class) kembalikan; else if (class [i] == string.class) return getContent (connection);} return null;}}}Penggunaannya sangat sederhana
Urlconnection.setContenthandlerFactory (echocontenthandlerfactory baru ());