-Declaração, mantenha-se longe das pessoas com morte cerebral. O núcleo deste blog não é o prefixo IF-ELSE+, mas como definir um protocolo privado através da estrutura de processamento do protocolo URL
A diferença entre um URI e um URL
Identificador de recursos uniformes URI (Identificador de Recursos Uniformes); URL (Local de Recurso Uniforme) Localizador de Recursos Uniformes (ou Localizador de Recursos Unificados); O URI é um conceito relativamente amplo. O URL é um tipo de URI e um subconjunto do mecanismo de nomeação de URI. Pode -se dizer que o URI é abstrato e o uso específico de URLs para localizar recursos. O URI geralmente aponta para não o caminho de recursos físicos, mas o identificador de recursos mapeados em todo o sistema. Os URLs são strings usados na Internet para descrever os recursos de informação, usados principalmente em vários programas de clientes e programas de servidores da WWW. O uso de URLs pode usar um formato unificado para descrever vários recursos de informação, incluindo arquivos, endereços e diretórios de servidores, etc.
1. Vamos primeiro prefácio
Estamos acostumados a http
Url url = novo url (http://www.apptest.com:8080/test/ios.php);
Devemos nos acostumar com isso também
Obviamente, também precisamos nos acostumar com o URL.
"https", "ftp", "mailto", "telnet", "file", "ldap", "gopher", "jdbc", "rmi", "jndi", "jar", "doc", "netdoc", "nfs", "verbatim", "finger", "daytime", "systemresource"
Url url = new url ("Oschina: //www.apptest.com: 8080/test/ios.php");Se você não estiver acostumado, as seguintes exceções sempre ocorrerão
java.net.MalformEdUrlexception: Protocolo desconhecido
Ao usar o AJAX nos navegadores Android, protocolos indefinidos não serão suportados.
2. Compreensão dos protocolos personalizados
Protocolo: No mundo da programação, o próprio protocolo é um conjunto de regras de restrição de entrada/OPUT. Portanto, nosso protocolo exato deve girar em torno da E/S, para que o protocolo aqui possa ser chamado de protocolo de E/S.
Iniciador de acordo: solicitação
Respondente de protocolo: resposta
As condições para o estabelecimento do Contrato são: Solicitação e resposta reconhecem o mesmo conjunto de acordos e se comuniquem de acordo com as restrições do contrato.
3. A relação entre protocolo personalizado e URL
Em Java, os protocolos personalizados exigem URLs?
A resposta é não.
De fato, em torno de E/S, nossas definições de regras estão completamente em nossas próprias mãos. Não diz que a terra não se virará depois de deixar o URL, e Java será destruído.
Por que personalizar o protocolo usando classes de URL?
A resposta é porque o URL é uma estrutura de processamento de comunicação de protocolo madura.
O protocolo URL personalizado mencionado aqui é essencialmente mais sobre expandir o protocolo por meio de regras existentes.
4. Prática de protocolo privado personalizado URL
Sabemos que os protocolos personalizados exigem resposta e solicitação, e ambas as partes precisam entender completamente o acordo um do outro. Por conveniência aqui, usamos o servidor de protocolo HTTP como uma resposta.
Aqui usamos o NGNIX Server + Php + FastCGI para criar a resposta, e o código de implantação é o seguinte
1. Defina a resposta
<? php $ raw_post_data = file_get_contents ('php: // input', 'r'); eco "-------/$ _ Post ------------------/n <br/>"; eco var_dump ($ _ post). "/n"; eco "------- php: // input --------------/n <br/>"; echo $ raw_post_data. "/n <br/>"; $ rs = JSON_ENCODE ($ _ Server); File_put_Contents ('text.html', $ rs); echo '' ';2. Defina a solicitação
2.1 Implementando a fábrica URLStreamHandlerFactory, usada principalmente para gerar processadores de protocolo
Classe pública ECHOURLSTREAMHANDLERFFACTORY IMPLEMENTES URLSTREAMHANDLERFACTORY {public urlStreamHandler CreateUrlStreamHandler (String Protocol) {// Personalize diferentes solicitações de esquema por meio do desvio aqui. Obviamente, as pessoas com morte cerebral pensam que esse é o código central. URL é uma estrutura de processamento de protocolo. Se o if-else for o núcleo, o Oracle irá à falência se (protocol.equals ("echo") || protocol.equals ("oschina")) {return echourlstreamhandler (); // instancia o manipulador de processamento de protocolo} retornar nulo; }}2.2 Implementando o UrlStreamHandler, a principal função é gerar o conector correspondente do protocolo
classe pública EchourlStreamHandler estende UrlStreamHandler {@OverRideProteged UrlConnection OpenEnconnection (URL U) lança IoException {return EchourlConnection (u); // também podemos realizar desvio correspondente aqui}} 2.3 Implemente o URLConnection, que é a personalização das regras de comunicação do protocolo. Aqui usamos o protocolo HTTP como regras de comunicação. Aqui imitamos solicitações de protocolo HTTP
(A seguir, é apresentado o código principal. O protocolo HTTP emprestado aqui. É claro que você pode interagir com vários protocolos usando o WebSocket, SMTP e FTP, em vez do prefixo de URL if-else+que as pessoas com morte cerebral me pedem para admitir )
classe pública ECHOURLCONNECTIONSETENDA URLCONNEÇÃO {conexão de soquete privado = null; public final estático int default_port = 80; public echourlConnection (url url) {super (url);} syncronized inputStream getinStream () throws ioException {se (! conectado) {conectada) (conectada); OutputStream getOutputStream () lança IoException {if (! ConnectEn) {Connect ();} retornar Connection.getOutputStream ();} public string getContentType () {return = Default_port; this.Connection = new Socket (url.gethost (), porta); // true significa desativar o buffer do soquete e enviar dados imediatamente. O valor padrão é falso // se a implementação subjacente do soquete não suporta a opção TCP_NODELAY, SOCKETEXCECTIONSTHIS.CONCONCONCONETION.ETCNODELAY; this.Connection.SetReUseadDress (true); // indica o tempo limite de espera ao receber dados, em milissegundos. O valor padrão é 0, o que significa que haverá infinito espera e nunca mais se sentirá, quando o sockettime é o socket de entrada, se houverá, o sockettime será o soquete, o socketentException será o soquete, o sockettexception será o soquete, o sockettexceptexextime será que o sockettime será o sockettime, que será que o sockettime será o socketime, que será o sockettime, que será o sockettime, que será o sockettime, que será o sockettime. Para ler os dados novamente this.Connection.SetSotimeout (30000); // indica se o soquete subjacente está imediatamente fechado // Quando o soquete é fechado, o soquete subjacente será atrasado em 5 segundos e depois fechado novamente. Após 5 segundos, todos os dados restantes que não foram enviados serão descartados. By default, if the Socket.close() method is executed, the method will return immediately, but the underlying Socket is not actually closed immediately// It will delay for a period of time until all the remaining data is sent, and the Socket will be truly closed and disconnected// Tips: When the program writes data through the output stream, it only means that the program submits a batch of data to the network, and the network is responsible for sending it to the receiver // Tips: When O programa fecha o soquete, é possível que o lote de dados ainda seja transmitido na rede e não tenha atingido o receptor // dicas: os "restantes dados restantes" mencionados aqui se refere a esses dados que ainda são transmitidos na rede e não foram recebidos pelo receptor. this.Connection.SetSendBuffersize (1024); // indica o tamanho do buffer em que os dados são recebidos. não transmitem dados um para o outro)? True é sim // seu valor padrão é falso, o que significa que o TCP não monitorará se a conexão é válida e clientes inativos podem existir permanentemente sem avisar que o servidor travou isso.connection.setkeepalive (true); // indica se ele suporta o envio de um byte de dados de emergência do TCP. O Socket.SendurGentData (Data) é usado para enviar um byte de dados de emergência do TCP // IT Padrões para False, ou seja, o receptor não faz nenhum processamento ao receber os dados de emergência e o descarta diretamente. Se o usuário desejar enviar dados de emergência, ele deve ser definido como TRUE // Após a configuração para True, o receptor colocará os dados de emergência recebidos na mesma fila que os dados normais this.Connection.SeSetoObinline (true); // Este método é usado para definir o tipo de serviço. O código seguinte solicita alta confiabilidade e serviço de transmissão de atraso mínimo (bits ou operações de 0x04 e 0x10) // a classe de soquete usa 4 números inteiros para representar o tipo de serviço // 0x02: baixo custo (o penultimado bit de binário é 1) // 0x04: alta confiabilidade (o bit de penultima é 1) // 08): o bits de penúltima é 1) // 0x8: 0x10: atraso mínimo (o quinto penúltimo bit de binário é 1) this.connection.setTrafficClass (0x04 | 0x10); // Este método é usado para definir a importância relativa do tempo de conexão, atraso e largura de banda (os três parâmetros deste método representam três indicadores dos dados de transmissão de rede) // de conexão com a conexão e o parâmetros de conexão com a conexão (//Time de conexão (os três parâmetros deste método representam três indicadores de transmissão de rede) // // 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 ("conexão: Keep-alive/r/n"); sb.append ("Data: sex, 22 de abril de 2016 13:17:35 gmt/r/n "); sb.append (" Vary: aceit-codificador/r/n "); sb.append (" content-type: application/x-www-corm-urlencoded, charset = utf-8/r/n "); sb.append (" conteúdo de conteúdo:: ") .Append (" nome = zhangsan & senha = 123456 ".getBytes (" utf-8 "). length) .append ("/r/n "); sb.append ("/r/n "); this.connection.getputStream (). write (sb.tostring () desconect () lança ioexception {if (conectado) {this.connection.close (); this.Connected = false;}}} Aqui, a definição de protocolo foi concluída.
Nosso código de teste é o seguinte
Tente se conectar a Oschina: // localhost: 8080/test/ios.php
Url.setUrlStreamHandlerFactory (new EchourlStreamHandlerFactory ()); // urlConnection.setContentHandlerFactory (new echocontentHandlerFactory ()); url url = new url ("Oschina: // localhost: 8080/test.hp.php"; conexão = (echourlConnection) url.openconnection (); conexão.SetDoOutput (true); conexão.SetDoinput (true); PrintWriter pw = new PrintWriter (new OutputStreamWriter (Connection.getOutputStream ())); pw.write ("name = zhangsan & senha = 123456"); pw.flush (); InputStream stream = conexão.getInputStream (); int len = -1; byte [] buf = novo byte [256]; while ((len = stream.read (buf, 0, 256))>-1) {string line = new String (buf, 0, len); if (line.endswith ("/r/n0/r/n/r/n") && len <256) {// o servidor retorna uma codificação de folha transferida,/r/n0/r/n/r/n significa que a leitura foi acabada, análise de bloqueio de chunked: http://dbscx.ite.e..combl/blked, http://dbscx.ite.e..combl, line.length ()-"/r/n0/r/n/r/n" .Length ()); System.out.println (linha); quebrar; } else {System.out.println (linha); }} pw.close (); stream.close ();Resultados de execução
O resultado mostra que o protocolo foi realmente definido com sucesso
Obviamente, a análise de dados acima não atende aos nossos requisitos porque é uma informação de codificação em parte. Como analisá -lo atende aos requisitos, mova -se :
Http racha de dados de codificação e análise do algoritmo
5 posteriormente, analisador de minetipo personalizado
O ContentHandlerFactory é fornecido em Java para analisar o minetipo. Formulamos nosso próprio analisador aqui. Obviamente, o JDK fornece mais abundantemente. O que fazemos aqui é atender às necessidades especiais.
classe pública echocontentHandler estende contentHandler {public Object getContent (conexão urlConnection) lança IoException {inputStream in = Connection.getInputStream (); BufferReader Br = new BufferReader (new inputStreamReader (in); retornar B.ReadLine ();} public object getCetCent (Urc) {InputStream in = Connection.getInputStream (); para (int i = 0; i <classes.length; i ++) {if (classes [i] == inputStream.class) retorna em; else if (classes [i] == string.class) retornar getContent (conexão);} retornar null;}}O uso é muito simples
UrlConnection.setContentHandlerFactory (novo echocontentHandlerFactory ());