Netty4.X 获取客户端IP

最近使用netty-4.0.23.Final 版本编写服务端代码,有个获取客户端代码的小需求,以前使用servlet开发时很机械的就:

1
2
3
4
5
6
String 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服务的程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public 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> {@Override
protected 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即可获取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class ServerHandler extends SimpleChannelInboundHandler<HttpObject> {
@Override
public 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了。


如果给你带来帮助,欢迎微信或支付宝扫一扫,赞一下。