Netty In Action中文版 – 第十二章:SPDY

释放双眼,带上耳机,听听看~!

Netty In Action中文版 – 第十二章:SPDY

Netty In Action中文版 - 第十二章:SPDY

本章我将不会直接翻译Netty In Action书中的原文,感觉原书中本章讲的很多废话,我翻译起来也吃力。所以,本章内容我会根据其他资料和个人理解来讲述。

12.1 SPDY概念及背景

        SPDY是Google开发的基于传输控制协议(TCP)的应用层协议,开发组正在推动SPDY成为正式标准(现为互联网草案).SPDY协议旨在通过压缩,多路复用和优先级来缩短网页的加载时间和提高安全性。(SPDY是Speedy的昵音,意思是更快)。

        为什么需要SPDY?SPDY协议只是在性能上对HTTP做了很大的优化,其核心思想是尽量减少连接个数,而对于HTTP的语义并没有做太大的修改。具体来说是,SPDY使用了HTTP的方法和页眉,但是删除了一些头并重写了HTTP中管理连接和数据转移格式的部分,所以基本上兼容HTTP的。

        Google在SPDY白皮书里表示要协议栈下面渗透并替换掉传输层协议(TCP),但是因为这样无论是部署起来还是实现起来暂时相当困难,因此Google准备先对应用层协议HTTP进行改进,先在SSL之上增加一个会话层来实现SPDY协议,而HTTP的GET和POST消息格式保持不变,即现有的所有服务端应用均不用做任何修改。因此在目前,SPDY的目的是为了加强HTTP,是对HTTP一个更好的实现和支持。至于未来SPDY得到广泛应用后会不会演一出狸猫换太子,替换掉HTTP并彻底颠覆整个Internet就是Google的事情了。

        距离万维网之父蒂姆·伯纳斯 – 李发明并推动HTTP成为如今互联网最流行的协议已经过去十几年了(现用HTTP 1.1规范也停滞了13年了),随着现在WEB技术的飞速发展尤其是HTML5的不断演进,包括WebSockets协议的出现以及当前网络环境的改变,传输内容的变化,当初的HTTP规范已经逐渐无法满足人们的需要了,HTTP需要进一步发展,因此HTTPbis工作组已经被组织并被授权考虑HTTP 2.0,希望能解决掉目前HTTP所带来的诸多限制。而SPDY正是Google在HTTP即将从1.1跨越到2.0之际推出的试图成为下一代互联网通信的协议,长期以来一直被认为是HTTP 2.0唯一可行选择。

       ** SPDY相比HTTP有如下优点:**

  1. SPDY多路复用,请求优化;而HTTP单路连接,请求低效
  2. SPDY支持服务器推送技术;而HTTP只允许由客户端主动发起请求
  3. SPDY压缩了HTTP头信息,节省了传输数据的带宽流量;而HTTP头冗余,同一个会话会反复送头信息
  4. SPDY强制使用SSL传输协议,全部请求SSL加密后,信息传输更安全

谷歌表示,引入SPDY协议后,在实验室测试中页面加载速度比原先快64%。

       ** 支持SPDY协议的浏览器:**

  • Google Chrome 19+和Chromium 19+
  • Mozilla Firefox 11+,从13开始默认支持
  • Opera 12.10+
  • Internet Explorer 11+

12.2本例子流程图

12.3 Netty中使用SPDY

        支持SPDY的的ChannelPipeline如下图:

        不支持SPDY的的ChannelPipeline如下图:

       ** 例子代码如下:**

**[java] **查看纯
文本

package  netty.in.action.spdy;
1.
1.
import  java.util.Arrays;
1.
import  java.util.Collections;
1.
import  java.util.List;
1.
1.
import  org.eclipse.jetty.npn.NextProtoNego.ServerProvider;
1.
1.
公共
类 DefaultServerProvider 
实现 ServerProvider {
1.

  1.     

private
static
final  List <String> PROTOCOLS = Collections.unmodifiableList(Arrays

  1.             .asList(

“spdy / 3.1” , 
“http / 1.1” , 
“http / 1.0” , 
“未知” ));
1.

  1.     

私人 字符串协议;
1.

  1.     

public  String getSelectedProtocol(){

  1.         

返回 协议;

  1.     }
  2.     

@覆盖

  1.     

public
void  protocolSelected(String arg0){

  1.         

这个.protocol = arg0;

  1.     }
  2.     

@覆盖

  1.     

public  List <String> protocols(){

  1.         

返回 PROTOCOLS;

  1.     }
  2.     

@覆盖

  1.     

public
void  unsupported(){

  1.         protocol = 

“http / 1.1” ;

  1.     }
  2. }

**[java] **查看纯
文本

package  netty.in.action.spdy;
1.
1.
import  io.netty.channel.ChannelFuture;
1.
import  io.netty.channel.ChannelFutureListener;
1.
import  io.netty.channel.ChannelHandlerContext;
1.
import  io.netty.channel.SimpleChannelInboundHandler;
1.
import  io.netty.handler.codec.http.DefaultFullHttpResponse;
1.
import  io.netty.handler.codec.http.FullHttpRequest;
1.
import  io.netty.handler.codec.http.FullHttpResponse;
1.
import  io.netty.handler.codec.http.HttpHeaders;
1.
import  io.netty.handler.codec.http.HttpResponseStatus;
1.
import  io.netty.handler.codec.http.HttpVersion;
1.
import  io.netty.util.CharsetUtil;
1.
1.
公共
类 HttpRequestHandler 
扩展 SimpleChannelInboundHandler <FullHttpRequest> {
1.

  1.     

@覆盖

  1.     

protected
void  channelRead0(ChannelHandlerContext ctx,FullHttpRequest请求)

  1.             

抛出 异常{

  1.         

如果 (HttpHeaders.is100ContinueExpected(request)){

  1.             send100Continue(CTX);
  2.         }
  3.         FullHttpResponse响应= 

新的 DefaultFullHttpResponse(

  1.                 request.getProtocolVersion(),HttpResponseStatus.OK);
  2.         。response.content()writeBytes(的getContent()的getBytes(CharsetUtil.UTF_8));
  3.         response.headers()。组(HttpHeaders.Names.CONTENT_TYPE,
  4.                 

“text / plain; charset = UTF-8” );

  1.         

boolean  keepAlive = HttpHeaders.isKeepAlive(request);

  1.         

if  (keepAlive){

  1.             response.headers()。组(HttpHeaders.Names.CONTENT_LENGTH,
  2.                     。response.content()readableBytes());
  3.             response.headers()。组(HttpHeaders.Names.CONNECTION,
  4.                     HttpHeaders.Values.KEEP_ALIVE);
  5.         }
  6.         ChannelFuture future = ctx.writeAndFlush(response);
  7.         

如果 (!keepAlive){

  1.             future.addListener(ChannelFutureListener.CLOSE);
  2.         }
  3.     }
  4.     

private
static
void  send100Continue(ChannelHandlerContext ctx){

  1.         FullHttpResponse响应= 

新的 DefaultFullHttpResponse(HttpVersion.HTTP_1_1,

  1.                 HttpResponseStatus.CONTINUE);
  2.         ctx.writeAndFlush(响应);
  3.     }
  4.     

protected  String getContent(){

  1.         

返回
“此内容通过HTTP \ r \ n传输” ;

  1.     }
  2.     

@覆盖

  1.     

public
void  exceptionCaught(ChannelHandlerContext ctx,Throwable cause)

  1.             

抛出 异常{

  1.         cause.printStackTrace();
  2.         ctx.close();
  3.     }
  4. }

**[java] **查看纯
文本

package  netty.in.action.spdy;
1.
1.
公共
类 SpdyRequestHandler 
扩展 HttpRequestHandler {
1.

  1.     

@覆盖

  1.     

protected  String getContent(){

  1.         

返回
“此内容通过SPDY \ r \ n传输” ;

  1.     }
  2. }

**[java] **查看纯
文本

package  netty.in.action.spdy;
1.
1.
import  io.netty.channel.ChannelInboundHandler;
1.
import  io.netty.handler.codec.spdy.SpdyOrHttpChooser;
1.
1.
import  javax.net.ssl.SSLEngine;
1.
1.
import  org.eclipse.jetty.npn.NextProtoNego;
1.
1.
public
class  DefaultSpdyOrHttpChooser 
extends  SpdyOrHttpChooser {
1.

  1.     

保护 DefaultSpdyOrHttpChooser(
int  maxSpdyContentLength, 
int  maxHttpContentLength){

  1.         

super (maxSpdyContentLength,maxHttpContentLength);

  1.     }
  2.     

@覆盖

  1.     

保护 SelectedProtocol getProtocol(SSLEngine引擎){

  1.         DefaultServerProvider提供程序=(DefaultServerProvider)NextProtoNego
  2.                 获得(发动机);
  3.         String protocol = provider.getSelectedProtocol();
  4.         

if  (protocol == 
null ){

  1.             

返回 SelectedProtocol.UNKNOWN;

  1.         }
  2.         

开关 (协议){

  1.         

案例
“spdy / 3.1” :

  1.             

返回 SelectedProtocol.SPDY_3_1;

  1.         

案例
“http / 1.0” :

  1.         

案例
“http / 1.1” :

  1.             

返回 SelectedProtocol.HTTP_1_1;

  1.         

默认值:

  1.             

返回 SelectedProtocol.UNKNOWN;

  1.         }
  2.     }
  3.     

@覆盖

  1.     

受保护的 ChannelInboundHandler createHttpRequestHandlerForHttp(){

  1.         

返回
新的 HttpRequestHandler();

  1.     }
  2.     

@覆盖

  1.     

受保护的 ChannelInboundHandler createHttpRequestHandlerForSpdy(){

  1.         

返回
新的 SpdyRequestHandler();

  1.     }
  2. }

**[java] **查看纯
文本

package  netty.in.action.spdy;
1.
1.
import  io.netty.channel.Channel;
1.
import  io.netty.channel.ChannelInitializer;
1.
import  io.netty.channel.ChannelPipeline;
1.
import  io.netty.handler.ssl.SslHandler;
1.
1.
import  javax.net.ssl.SSLContext;
1.
import  javax.net.ssl.SSLEngine;
1.
1.
import  org.eclipse.jetty.npn.NextProtoNego;
1.
1.
公共
类 SpdyChannelInitializer 
扩展 ChannelInitializer <Channel> {

  1.     

私人
最终 SSLContext上下文;
1.

  1.     

公共 SpdyChannelInitializer(SSLContext上下文){

  1.         

this .context = context;

  1.     }
  2.     

@覆盖

  1.     

protected
void  initChannel(Channel ch) 
引发 Exception {

  1.         ChannelPipeline pipeline = ch.pipeline();
  2.         SSLEngine engine = context.createSSLEngine();
  3.         engine.setUseClientMode(

false );

  1.         NextProtoNego.put(引擎, 

新的 DefaultServerProvider());

  1.         NextProtoNego.debug = 

true ;

  1.         pipeline.addLast(

“sslHandler” , 
新的 SslHandler(引擎));

  1.         pipeline.addLast(

“选择器” ,

  1.                 

新 DefaultSpdyOrHttpChooser(
1024  * 
1024 , 
1024  * 
1024 ));

  1.     }
  2. }

**[java] **查看纯
文本

package  netty.in.action.spdy;
1.
1.
import  io.netty.bootstrap.ServerBootstrap;
1.
import  io.netty.channel.Channel;
1.
import  io.netty.channel.ChannelFuture;
1.
import  io.netty.channel.nio.NioEventLoopGroup;
1.
import  io.netty.channel.socket.nio.NioServerSocketChannel;
1.
import  io.netty.example.securechat.SecureChatSslContextFactory;
1.
1.
import  java.net.InetSocketAddress;
1.
1.
import  javax.net.ssl.SSLContext;
1.
1.
公共
类 SpdyServer {
1.

  1.     

private
final  NioEventLoopGroup group = 
new  NioEventLoopGroup();

  1.     

私人
最终 SSLContext上下文;

  1.     

私人 频道频道;
1.

  1.     

公共 SpdyServer(SSLContext上下文){

  1.         

this .context = context;

  1.     }
  2.     

公共 ChannelFuture开始(InetSocketAddress地址){

  1.         ServerBootstrap bootstrap = 

new  ServerBootstrap();

  1.         bootstrap.group(组).channel(NioServerSocketChannel。

类)

  1.                 .childHandler(

新的 SpdyChannelInitializer(上下文));

  1.         ChannelFuture future = bootstrap.bind(address);
  2.         future.syncUninterruptibly();
  3.         channel = future.channel();
  4.         

回报 未来;

  1.     }
  2.     

public
void  destroy(){

  1.         

if  (channel!= 
null ){

  1.             channel.close();
  2.         }
  3.         group.shutdownGracefully();
  4.     }
  5.     

public
static
void  main(String [] args){

  1.         SSLContext context = SecureChatSslContextFactory.getServerContext();
  2.         

最终 SpdyServer端点= 
新的 SpdyServer(上下文);

  1.         ChannelFuture future = endpoint.start(

new  InetSocketAddress(
4096 ));

  1.         Runtime.getRuntime()。addShutdownHook(

new  Thread(){

  1.             

@覆盖

  1.             

public
void  run(){

  1.                 endpoint.destroy();
  2.             }
  3.         });
  4.         。future.channel()closeFuture()syncUninterruptibly();
  5.     }
  6. }

使用SSL需要使用到的SSLContext,下面代买是获取的SSLContext对象:

**[java] **查看纯
文本

  1. / *
  2.  *版权所有2012 The Netty项目
  3.  *
  4.  * Netty项目根据Apache许可证将此文件授权给您,
  5.  *版本2.0(“许可证”); 除遵守规定外,您不得使用此文件
  6.  *与许可证。您可以在以下地址获得许可证副本:
  7.  *
  8.  * http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  *除非适用法律要求或书面同意,软件
  11.  *根据许可证分发是按“原样”基础分发的,没有
  12.  *任何种类的保证或条件,无论是明示还是暗示。看到了
  13.  *用于管理权限和限制的特定语言的许可证
  14.  *根据许可证。
  15.  * /

package  netty.in.action.spdy;
1.
1.
import  javax.net.ssl.ManagerFactoryParameters;
1.
import  javax.net.ssl.TrustManager;
1.
import  javax.net.ssl.TrustManagerFactorySpi;
1.
import  javax.net.ssl.X509TrustManager;
1.
import  java.security.InvalidAlgorithmParameterException;
1.
import  java.security.KeyStore;
1.
import  java.security.KeyStoreException;
1.
import  java.security.cert.X509Certificate;
1.

  1. / **
  2.  *接受任何证书的虚假{TrustManagerFactorySpi}
  3.  *即使它无效。
  4.  * /

公共
类 SecureChatTrustManagerFactory 
扩展 TrustManagerFactorySpi {
1.

  1.     

private
static
final  TrustManager DUMMY_TRUST_MANAGER = 
new  X509TrustManager(){

  1.         

@覆盖

  1.         

public  X509Certificate [] getAcceptedIssuers(){

  1.             

返回
新的 X509Certificate [
0 ];

  1.         }
  2.         

@覆盖

  1.         

public
void  checkClientTrusted(X509Certificate [] chain,String authType){

  1.             

//永远相信 – 这是一个例子。

  1.             

//你应该在现实世界中做点什么。

  1.             

//只有启用了客户端证书身份验证后,您才会到达此处,

  1.             

//如SecureChatSslContextFactory中所述。

  1.             通信System.err.println(
  2.                     

“UNKNOWN CLIENT CERTIFICATE:”  + chain [
0 ] .getSubjectDN());

  1.         }
  2.         

@覆盖

  1.         

public
void  checkServerTrusted(X509Certificate [] chain,String authType){

  1.             

//永远相信 – 这是一个例子。

  1.             

//你应该在现实世界中做点什么。

  1.             通信System.err.println(
  2.                     

“UNKNOWN SERVER CERTIFICATE:”  + chain [
0 ] .getSubjectDN());

  1.         }
  2.     };
  3.     

public
static  TrustManager [] getTrustManagers(){

  1.         

返回
新的 TrustManager [] {DUMMY_TRUST_MANAGER};

  1.     }
  2.     

@覆盖

  1.     

受保护的 TrustManager [] engineGetTrustManagers(){

  1.         

返回 getTrustManagers();

  1.     }
  2.     

@覆盖

  1.     

protected
void  engineInit(KeyStore keystore) 
抛出 KeyStoreException {

  1.         

// 没用过

  1.     }
  2.     

@覆盖

  1.     

protected
void  engineInit(ManagerFactoryParameters managerFactoryParameters)

  1.             

抛出 InvalidAlgorithmParameterException {

  1.         

// 没用过

  1.     }
  2. }

**[java] **查看纯
文本

  1. / *
  2.  *版权所有2012 The Netty项目
  3.  *
  4.  * Netty项目根据Apache许可证将此文件授权给您,
  5.  *版本2.0(“许可证”); 除遵守规定外,您不得使用此文件
  6.  *与许可证。您可以在以下地址获得许可证副本:
  7.  *
  8.  * http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  *除非适用法律要求或书面同意,软件
  11.  *根据许可证分发是按“原样”基础分发的,没有
  12.  *任何种类的保证或条件,无论是明示还是暗示。看到了
  13.  *用于管理权限和限制的特定语言的许可证
  14.  *根据许可证。
  15.  * /

package  netty.in.action.spdy;
1.
1.
import  java.io.ByteArrayInputStream;
1.
import  java.io.InputStream;
1.

  1. / **
  2.  *提供所有必需信息的虚假密钥存储区
  3.  *创建一个示例SSL连接。
  4.  *
  5.  *要生成一个伪造的密钥存储:
  6.  * <pre>
  7.  * keytool -genkey -alias securechat -keysize 2048 -validity 36500
  8.  * -keyalg RSA -dname“CN = securechat”
  9.  * – 关键秘密 – 通道秘密
  10.  * -keystore cert.jks
  11.  * </ pre>
  12.  * /

公共
最终
课 SecureChatKeyStore {

  1.     

private
static
final
short [] DATA = {

  1.         

0xFE的, 
0xed , 
0xFE时, 
0xed , 
0×00 , 
0×00 , 
0×00 , 
0×02 ,

  1.         

0×00 , 
0×00 , 
0×00 , 
0×02 , 
0×00 , 
0×00 , 
0×00 , 
0×01 ,

  1.         

为0x00 , 
0x07的, 
0x65 , 
0x78 , 
0x61 , 
0x6d , 
0x70 , 
0x6c ,

  1.         

0x65 , 
0×00 , 
0×00 , 
0×01 , 
0X1A , 
0x9f , 
0×57 , 
0xA5的,

  1.         

0×27 , 
0×00 , 
0×00 , 
0×01 , 
为0x9A , 
的0x30 , 
为0x82 , 
0×01 ,

  1.         

0x96 , 
的0x30 , 
0x0E的, 
0×06 , 
0X0A , 
0x2B访问, 
0×06 , 
0×01 ,

  1.         

0×04 , 
0×01 , 
0x2a , 
0×02 , 
0×11 , 
0×01 , 
0×01 , 
0×05 ,

  1.         

为0x00 , 
0x04访问, 
为0x82 , 
0×01 , 
为0x82 , 
0x48 , 
0x6d , 
0xcf ,

  1.         

0x16 , 
0xB5执行, 
为0x50 , 
位0x95 , 
0x36 , 
为0xBF , 
0X47 , 
0×27 ,

  1.         

为0x50 , 
将0x58 , 
0X0D , 
0xa2 , 
0×52 , 
0x7e格式, 
0x25 , 
是0xAB ,

  1.         

0×14 , 
0X1A , 
值为0x26 , 
0x5e , 
0x2d , 
0x8a , 
0×23 , 
0×90 ,

  1.         

0X60 , 
0x7f的, 
0×12 , 
为0x20 , 
0x56储存, 
0xd1 , 
0x43中, 
0xa2 ,

  1.         

0x6b , 
0X47 , 
0x5d , 
0xed , 
0x9d , 
0xd4 , 
为0xE5 , 
0×83 ,

  1.         

0×28 , 
0x89上, 
为0xC2 , 
0x16 , 
0x4c , 
0x76 , 
0×06 , 
写入0xAD ,

  1.         

为0x8E , 
0x8c , 
0x29 , 
0X1A , 
0x9b , 
为0x0F , 
0xdd , 
0x60的,

  1.         

0x4b , 
0xb4 , 
0X62 , 
为0x82 , 
0x9e , 
0x4a , 
0x63 , 
0×83 ,

  1.         

0x2E之间, 
0xd2 , 
0x43中, 
0x78 , 
为0xC2 , 
0x32 , 
0x1F的, 
0x60的,

  1.         

0xa9 , 
0x8a , 
0x7f的, 
为0x0F , 
0x7c , 
0xa6 , 
0x1d , 
0xe6 ,

  1.         

0x92 , 
0x9e , 
0×52 , 
0xc7 , 
0x7d , 
为0xBB , 
0x35 , 
0x3b ,

  1.         

和0xAA , 
0x89上, 
0x73 , 
0x4c , 
0xFB的才能, 
0x99 , 
0x54 , 
0x97 ,

  1.         

0x99 , 
0×28 , 
0x6e , 
0x66 , 
0x5b , 
0xf7 , 
0x9b , 
0x7e格式,

  1.         

0x6d , 
0x8a , 
值为0x2F , 
0xFA回应, 
0xc3 , 
0X1E , 
0x71 , 
0xb9 ,

  1.         

0xbd , 
值为0x8F , 
0xc5 , 
0x63 , 
0x25 , 
0X31 , 
0×20 , 
0×02 ,

  1.         

0xFF的, 
0×02 , 
0XF0 , 
0xc9 , 
0x2c上, 
0xdd , 
0x3a , 
为0x10 ,

  1.         

的0x30 , 
是0xAB , 
为0xE5 , 
0xAD,将, 
0x3D之间, 
0X1A , 
为0x82 , 
0x77 ,

  1.         

0×46 , 
0xed , 
×03 , 
0x38 , 
0xa4 , 
0x73 , 
0x6d , 
0x36 ,

  1.         

0x36 , 
0x33 , 
0x70 , 
0xb2 , 
0x63 , 
0x20的, 
0xca , 
×03 ,

  1.         

为0xBF , 
0x5a , 
0xF4中, 
0x7c , 
0x35 , 
0XF0 , 
0x63 , 
0X1A ,

  1.         

0×12 , 
0x33 , 
0×12 , 
将0x58 , 
0xd9 , 
0xa2 , 
0x63 , 
0x6b ,

  1.         

0x63 , 
为0x82 , 
×41 , 
0x65 , 
0x70 , 
0x37符号, 
0x4b , 
0x99 ,

  1.         

0×04 , 
0x9f , 
0xdd , 
0x5e , 
0×07 , 
0×01 , 
位0x95 , 
0x9f ,

  1.         

0x36 , 
0xe8 , 
0xc3 , 
0x66 , 
0x2a , 
为0x21 , 
0×69 , 
0x68 ,

  1.         

0x40的, 
0xe6 , 
0xbc , 
为0xBB , 
0x85 , 
0×81 , 
0×21 , 
0×13 ,

  1.         

0xe6 , 
0xa4 , 
0xcf , 
0xd3 , 
0×67 , 
0xe3 , 
0xfd , 
0x75 ,

  1.         

0XF0 , 
0xdf , 
0×83 , 
0xe0的, 
0xc5 , 
0x36 , 
×09 , 
0xac ,

  1.         

0x1b , 
0xd4 , 
0xf7 , 
0x2a , 
0×23 , 
×57 , 
为0x1C , 
0x5c ,

  1.         

为0x0F , 
0xF4中, 
0xcf , 
0xa2 , 
0xcf , 
0xf5 , 
0xbd , 
为0x9c ,

  1.         

0×69 , 
0x98在全局, 
0x78 , 
0x3a , 
0x25 , 
0xe4 , 
0xfd , 
0x85 ,

  1.         

为0x11 , 
含有0xCC , 
0x7d , 
0xef , 
将0xEB , 
0x74 , 
0x60的, 
0xb1 ,

  1.         

0xb7 , 
0xFB的才能, 
为0x1F , 
0x0E的, 
0X62 , 
为0xFF , 
0xFE时, 
×09 ,

  1.         

0X0A , 
0xc3 , 
0x80的, 
值为0x2F , 
0x10的, 
×49 , 
0x89上, 
0x78 ,

  1.         

0xd2 , 
0×08 , 
0xFA回应, 
0x89上, 
为0x22 , 
0×45 , 
0x91 , 
为0x21 ,

  1.         

0xbc , 
0×90 , 
0x3E的, 
写入0xAD , 
0xb3 , 
0X0A , 
0xb4 , 
为0x0E ,

  1.         

为0x1c , 
0xa1 , 
0x93 , 
0x92 , 
0xd8 , 
0x72 , 
0x07的, 
0x54 ,

  1.         

0X60 , 
0xe7 , 
0x91 , 
0xFC有, 
0xd9 , 
为0x3C , 
0xe1 , 
0x6f ,

  1.         

0×08 , 
0xe4 , 
0x56储存, 
0xf6 , 
0x0B中, 
0XB0 , 
为0x3C , 
0x39 ,

  1.         

0x8a , 
0x2d , 
0x48 , 
0x44进行, 
0×28 , 
0×13 , 
0xca , 
0xe9 ,

  1.         

0xf7 , 
0xA3执行, 
0xb6 , 
0x8a , 
0x5F的, 
0X31 , 
0xa9 , 
0x72 ,

  1.         

0xf2 , 
写0xDE , 
0x96 , 
0xf2 , 
0xb1 , 
0x53 , 
0xb1 , 
0x3E的,

  1.         

0X24 , 
0×57 , 
0xfd , 
为0x18 , 
0×45 , 
为0x1F , 
0xc5 , 
0x33 ,

  1.         

0x1b , 
0xa4 , 
0xe8 , 
为0x21 , 
0xFA回应, 
为0x0E , 
0xb2 , 
0xb9 ,

  1.         

0xcb , 
0xc7 , 
0x07的, 
×41 , 
0xdd , 
值为0x2F , 
0xb6 , 
的0x6A ,

  1.         

0×23 , 
为0x18 , 
0xed , 
0xc1 , 
0xef , 
0xe2 , 
0x4b , 
0xec ,

  1.         

0xc9 , 
0xba , 
0xFB的才能, 
0×46 , 
×43 , 
0×90 , 
0xd7 , 
0xB5执行,

  1.         

0x68 , 
0×28 , 
0X31 , 
0x2B访问, 
0x8d , 
0xa8 , 
0x51 , 
0x63 ,

  1.         

0xf7 , 
0x53 , 
0x99 , 
0x19 , 
0x68 , 
0x85 , 
0x66 , 
0×00 ,

  1.         

0×00 , 
0×00 , 
0×01 , 
0×00 , 
0×05 , 
将0x58 , 
0x2E之间, 
0x35 ,

  1.         

的0x30 , 
0x39 , 
0×00

给TA打赏
共{{data.count}}人
人已打赏
安全技术

详解Node.js API系列 Http模块(2) CNodejs爬虫实现

2021-12-21 16:36:11

安全技术

从零搭建自己的SpringBoot后台框架(二十三)

2022-1-12 12:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索