【发布时间】:2015-11-03 13:35:14
【问题描述】:
我想用 SSL 编写一个 UDP Netty 服务器/客户端。我以类似于 TCP Netty Server/Client 的方式进行操作,效果很好。但我遇到了一个例外:
javax.net.ssl.SSLException:Received close_notify during handskake,close channel...
我的网络是 3.x,SSL 配置运行良好。这是我的 Udp 服务器和客户端的一些代码。服务器:
serverBootstrap = new ConnectionlessBootstrap(
new NioDatagramChannelFactory(Executors.newCachedThreadPool(),maxThreads));
serverBootstrap.setOption("receiveBufferSizePredictorFactory",
new FixedReceiveBufferSizePredictorFactory(8192));
ChannelPipelineFactory fac = null;
try {
ServiceDecoder serviceProcessor = (ServiceDecoder)Class.forName(serviceDecoderName).newInstance();
Class<? extends ChannelPipelineFactory> clazz = (Class<? extends ChannelPipelineFactory>) Class
.forName(msgFactoryName);
Constructor ctor = clazz.getConstructor(ChannelProcessor.class,
ChannelGroup.class, CounterGroup.class, CounterGroupExt.class, String.class,ServiceDecoder.class,
String.class, Integer.class, String.class, String.class, Boolean.class,Integer.class,Boolean.class,Boolean.class,Context.class);
logger.info("Using channel processor:{}", getChannelProcessor().getClass().getName());
fac = (ChannelPipelineFactory) ctor.newInstance(
getChannelProcessor(), allChannels, counterGroup, counterGroupExt, "udp", serviceProcessor,
messageHandlerName, maxMsgLength, topic, attr, filterEmptyMsg, maxConnections, isCompressed,enableSsl,context);
} catch (Exception e) {
logger.error(
"Simple Udp Source start error, fail to construct ChannelPipelineFactory with name {}, ex {}",
msgFactoryName, e);
stop();
throw new FlumeException(e.getMessage());
}
serverBootstrap.setPipelineFactory(fac);
try {
if (host == null) {
nettyChannel = serverBootstrap
.bind(new InetSocketAddress(port));
} else {
nettyChannel = serverBootstrap.bind(new InetSocketAddress(host,
port));
}
服务器中的管道:
if(enableSsl) {
cp.addLast("ssl", sslInit());
}
if (processor != null) {
try {
Class<? extends SimpleChannelHandler> clazz = (Class<? extends SimpleChannelHandler>) Class
.forName(messageHandlerName);
Constructor<?> ctor = clazz.getConstructor(
ChannelProcessor.class, ServiceDecoder.class, ChannelGroup.class,
CounterGroup.class, CounterGroupExt.class, String.class, String.class,
Boolean.class, Integer.class, Integer.class, Boolean.class);
SimpleChannelHandler messageHandler = (SimpleChannelHandler) ctor
.newInstance(processor, serviceProcessor, allChannels,
counterGroup, counterGroupExt, topic, attr,
filterEmptyMsg, maxMsgLength, maxConnections, isCompressed);
cp.addLast("messageHandler", messageHandler);
} catch (Exception e) {
e.printStackTrace();
}
}
if (this.protocolType.equalsIgnoreCase(ConfigConstants.UDP_PROTOCOL)) {
cp.addLast("execution", executionHandler);
}
客户:
private ConnectionlessBootstrap clientBootstrap;
clientBootstrap = new ConnectionlessBootstrap(
new NioDatagramChannelFactory(Executors.newCachedThreadPool()));
clientBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("sslHandler", sslInit());
pipeline.addLast("orderHandler",new ExecutionHandler(
new OrderedMemoryAwareThreadPoolExecutor(cores * 2,
1024 * 1024, 1024 * 1024)));
return pipeline;
}
});
在客户端发送消息的两个函数:
public void sendMessage(byte[] data) {
ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(data);
sendMessage(buffer);
}
public void sendMessage(ChannelBuffer buffer) {
Random random = new Random();
Channel channel = channelList.get(random.nextInt(channelList.size()));
if(!channel.isConnected()){
channel.close();
ChannelFuture cf = clientBootstrap
.connect(new InetSocketAddress(ip, port));
if(cf.awaitUninterruptibly(3000, TimeUnit.MILLISECONDS)){
channel = cf.getChannel();
}else {
channelList.remove(channel);
return;
}
}
ChannelFuture future = channel.write(buffer);
if(!future.awaitUninterruptibly(3, TimeUnit.SECONDS)){
logger.warn("send failed!{}",future.getCause());
}else {
sendCnt.incrementAndGet();
}
}
我怀疑 UDP Netty Server/Client 是否支持 SSL。任何提示都表示赞赏。
【问题讨论】:
-
我也这么怀疑。我很惊讶你能做到这一点。您与哪个同行交流?
-
@EJP 看了几天flume代码,我只想加密从netty客户端到服务器(即flume源)传输的数据,并且已经完成了TCP,但是当我尝试了UDP,它失败了。你能解释一下为什么 UDP 不支持 SSL 吗?非常感谢。
-
我没有说 UDP 不能支持 SSL。我同意你的评论,也许 Netty 做得不好。