最近使用netty-4.0.23.Final 版本编写服务端代码,有个获取客户端代码的小需求,以前使用servlet开发时很机械的就:StringipAddr="0.0.0.0";
if(reqest.getHeader("X-Forwarded-For")==null){
ipAddr=reqest.getRemoteAddr();
}else{
ipAddr=req.getHeader("X-Forwarded-For");
}
ps:X-Forwarded-For 是使用了代理(如nginx)会附加在HTTP头域上的。
理解好HTTP协议基础知识很重要这里不陈述。
Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序,支持多种协议,当然也支持HTTP协议。
启动Netty服务的程序:publicvoidstart()throwsException{
EventLoopGroupbossGroup=newNioEventLoopGroup(1);
EventLoopGroupworkerGroup=newNioEventLoopGroup();
try{
ServerBootstrapbootstrap=newServerBootstrap();
bootstrap.option(ChannelOption.SO_BACKLOG,1024);
bootstrap.group(bossGroup,workerGroup)
.channel(NioServerSocketChannel.class)
.handler(newLoggingHandler(LogLevel.INFO))
.childHandler(newServerHandlerInitializer());
Channelch=bootstrap.bind(8080).sync().channel();
System.err.println("Openyourwebbrowserandnavigateto"
+("http")+"://127.0.0.1:8080/");
ch.closeFuture().sync();
}catch(Exceptione){
e.printStackTrace();
}finally{
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
publicclassServerHandlerInitializerextendsChannelInitializer{
@Override
protectedvoidinitChannel(SocketChannelchannel)throwsException{
ChannelPipelinep=channel.pipeline();
p.addLast(newHttpRequestDecoder());
p.addLast(newHttpResponseEncoder());
p.addLast(newServerHandler());
}
}
看出NioServerSocketChannel类的源码可以知道是对java.nio.channels.ServerSocketChannel重新封装,所以在获取客户端IP时调用remoteAddress()强转成.InetSocketAddress即可获取。publicclassServerHandlerextendsSimpleChannelInboundHandler{
@Override
publicvoidchannelRead0(ChannelHandlerContextctx,HttpObjectmsg)
throwsException{
if(msginstanceofHttpRequest){
HttpRequestmReq=(HttpRequest)msg;
StringclientIP=mReq.headers().get("X-Forwarded-For");
if(clientIP==null){
InetSocketAddressinsocket=(InetSocketAddress)ctx.channel()
.remoteAddress();
clientIP=insocket.getAddress().getHostAddress();
}
}
}
}
这样我们就可以获取到客户端的IP了。