1. 程式人生 > >Netty獲取客戶端IP

Netty獲取客戶端IP

    最近使用netty-4.0.23.Final 版本編寫服務端程式碼,有個獲取客戶端程式碼的小需求,以前使用servlet開發時很機械的就:

123456String ipAddr="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服務的程式:

123456789101112131415161718192021222324252627282930313233public void start() throws Exception {EventLoopGroup bossGroup = new NioEventLoopGroup(1);EventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap bootstrap = 
new ServerBootstrap();bootstrap.option(ChannelOption.SO_BACKLOG, 1024);bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ServerHandlerInitializer());Channel ch = bootstrap.bind(8080).sync().channel();System.err.println(
"Open your web browser and navigate to "+ ("http") + "://127.0.0.1:8080/");ch.closeFuture().sync();catch (Exception e) {e.printStackTrace();finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}public class ServerHandlerInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel channel) throws Exception {ChannelPipeline p = channel.pipeline();p.addLast(new HttpRequestDecoder());p.addLast(new HttpResponseEncoder());p.addLast(new ServerHandler());}}

看出NioServerSocketChannel類的原始碼可以知道是對java.nio.channels.ServerSocketChannel重新封裝,所以在獲取客戶端IP時呼叫remoteAddress()強轉成java.net.InetSocketAddress即可獲取。

123456789101112131415public class ServerHandler extends SimpleChannelInboundHandler<HttpObject> {@Overridepublic void channelRead0(ChannelHandlerContext ctx, HttpObject msg)throws Exception {if (msg instanceof HttpRequest) {HttpRequest mReq = (HttpRequest) msg;String clientIP = mReq.headers().get("X-Forwarded-For");if (clientIP == null) {InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();clientIP = insocket.getAddress().getHostAddress();}}}}

這樣我們就可以獲取到客戶端的IP了。