我想用SSL编写UDP Netty Server / Client。我这样做的方式类似于TCP Netty Server / Client,效果很好。但我遇到了一个例外:
javax.net.ssl.SSLException:Received close_notify during handskake,close channel...
我的netty是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。任何提示都表示赞赏。