Java netty服务器上的StringEncoder和StringDecoder的正确用法是什么?

Java netty服务器上的StringEncoder和StringDecoder的正确用法是什么?,java,io,client-server,netty,nio,Java,Io,Client Server,Netty,Nio,下面的基于字符串的服务器在功能上等同于它的数据报服务器吗 我看到的唯一显著区别,也是我试图实现的唯一区别,是从NioDatagramChannel到nioServerSocketChannel。处理程序之间有一些细微的区别,但是两个处理程序是否都用nextQuote()响应“QOTM” 为了简洁和理智,我不能包括客户。我对netty不熟悉,而且我找不到关于这个主题的4.x文档。他说: 7.2.4 MessageToMessageDecoder–如果要将消息解码为另一种类型的消息MessageTo

下面的基于字符串的服务器在功能上等同于它的数据报服务器吗

我看到的唯一显著区别,也是我试图实现的唯一区别,是从
NioDatagramChannel
nioServerSocketChannel
。处理程序之间有一些细微的区别,但是两个处理程序是否都用
nextQuote()响应“QOTM”

为了简洁和理智,我不能包括客户。我对netty不熟悉,而且我找不到关于这个主题的4.x文档。他说:

7.2.4 MessageToMessageDecoder–如果要将消息解码为另一种类型的消息MessageToMessageDecoder,请在运行中解码POJO 这是一条路要走。它提供了一种简单的方法。语义是 与我们前面解释的所有其他解码器完全相同

但为了简单起见,我只是暂时尝试使用字符串en/de编码器。我是否在服务器中正确使用它们

另见:

数据报服务器:

package net.bounceme.dur.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import java.util.logging.Logger;
import net.bounceme.dur.netty.datagram.DatagramServerInitializer;

public final class DatagramServer {

    private static final Logger log = Logger.getLogger(DatagramServer.class.getName());

    public void start() throws InterruptedException {
        MyProps p = new MyProps();
        int port = p.getServerPort();
        pingPong(port);
    }


    private void pingPong(int port) throws InterruptedException {
        log.fine("which handler?");
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    .handler(new DatagramServerInitializer());
            b.bind(port).sync().channel().closeFuture().await();
        } finally {
            group.shutdownGracefully();
        }
    }
}   
字符串服务器:

package net.bounceme.dur.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import java.util.logging.Logger;
import net.bounceme.dur.netty.string.StringServerInitializer;

public final class StringServer {

    private static final Logger log = Logger.getLogger(StringServer.class.getName());

    public void start() throws InterruptedException {
        MyProps p = new MyProps();
        int port = p.getServerPort();
        pingPong(port);
    }

    private void pingPong(int port) throws InterruptedException {
        log.fine("which handler?");
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    .handler(new StringServerInitializer());
            b.bind(port).sync().channel().closeFuture().await();
        } finally {
            group.shutdownGracefully();
        }
    }
}
数据报服务器处理程序:

package net.bounceme.dur.netty.datagram;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;
import java.util.Random;
import java.util.logging.Logger;

public class DatagramServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {

    private static final Logger log = Logger.getLogger(DatagramServerHandler.class.getName());
    private static final Random random = new Random();

    public DatagramServerHandler() {
        log.info("..started..");
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        ctx.writeAndFlush(nextQuote());
    }

    // Quotes from Mohandas K. Gandhi:
    private static final String[] quotes = {
        "Where there is love there is life.",
        "First they ignore you, then they laugh at you, then they fight you, then you win.",
        "Be the change you want to see in the world.",
        "The weak can never forgive. Forgiveness is the attribute of the strong.",};

    private static String nextQuote() {
        int quoteId;
        synchronized (random) {
            quoteId = random.nextInt(quotes.length);
        }
        return quotes[quoteId];
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
        log.info(packet.toString());
        if ("QOTM?".equals(packet.content().toString(CharsetUtil.UTF_8))) {
            ctx.write(new DatagramPacket(
                    Unpooled.copiedBuffer("QOTM: " + nextQuote(), CharsetUtil.UTF_8), packet.sender()));
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.severe(cause.toString());
    }
}
package net.bounceme.dur.netty.string;

import net.bounceme.dur.netty.datagram.DatagramServerHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import java.util.Random;
import java.util.logging.Logger;

public class StringServerHandler extends SimpleChannelInboundHandler<String> {

    private static final Logger log = Logger.getLogger(DatagramServerHandler.class.getName());
    private static final Random random = new Random();

    public StringServerHandler() {
        log.info("..started..");
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        ctx.writeAndFlush(nextQuote());
    }

    // Quotes from Mohandas K. Gandhi:
    private static final String[] quotes = {
        "Where there is love there is life.",
        "First they ignore you, then they laugh at you, then they fight you, then you win.",
        "Be the change you want to see in the world.",
        "The weak can never forgive. Forgiveness is the attribute of the strong.",};

    private static String nextQuote() {
        int quoteId;
        synchronized (random) {
            quoteId = random.nextInt(quotes.length);
        }
        return quotes[quoteId];
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.severe(cause.toString());
    }

    @Override
    protected void channelRead0(ChannelHandlerContext chc, String msg) throws Exception {
        System.err.println(msg);
        if ("QOTM?".equals(msg)) {
            chc.writeAndFlush(nextQuote());
        } else {
            log.warning(msg);  //never executes
        }
    }
}
包net.bounceme.dur.netty.datagram;
导入io.netty.buffer.Unpooled;
导入io.netty.channel.ChannelHandlerContext;
导入io.netty.channel.SimpleChannelInboundHandler;
导入io.netty.channel.socket.DatagramPacket;
导入io.netty.util.CharsetUtil;
导入java.util.Random;
导入java.util.logging.Logger;
公共类DatagramServerHandler扩展了SimpleChannelInboundHandler{
私有静态最终记录器log=Logger.getLogger(DatagramServerHandler.class.getName());
私有静态最终随机=新随机();
公共DatagramServerHandler(){
log.info(“…开始…”);
}
@凌驾
公共无效channelActive(ChannelHandlerContext ctx)引发异常{
超级通道激活(ctx);
ctx.writeAndFlush(nextQuote());
}
//莫汉达斯·甘地的名言:
私有静态最终字符串[]引号={
“哪里有爱,哪里就有生命。”,
“首先他们忽视你,然后他们嘲笑你,然后他们和你打架,然后你赢了。”,
“成为你想在世界上看到的改变。”,
“弱者永远不会原谅。原谅是强者的属性。”,};
私有静态字符串nextQuote(){
int quoteId;
同步(随机){
quoteId=random.nextInt(quotes.length);
}
返回引号[quoteId];
}
@凌驾
public void channelRead0(ChannelHandlerContext ctx,DatagramPacket数据包)引发异常{
log.info(packet.toString());
if(“QOTM?”.equals(packet.content().toString(CharsetUtil.UTF_8))){
ctx.write(新数据包)(
copiedBuffer(“QOTM:+nextQuote(),CharsetUtil.UTF_8),packet.sender());
}
}
@凌驾
公共无效channelReadComplete(ChannelHandlerContext ctx){
ctx.flush();
}
@凌驾
公共无效例外情况(ChannelHandlerContext ctx,可丢弃原因){
log.severy(原因.toString());
}
}
数据报服务器初始值设定项:

package net.bounceme.dur.netty.datagram;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import java.util.logging.Logger;

public class DatagramServerInitializer extends ChannelInitializer<NioDatagramChannel> {

    private static final Logger log = Logger.getLogger(DatagramServerInitializer.class.getName());

    public DatagramServerInitializer() {
        log.info("..initializing..");
    }

    @Override
    protected void initChannel(NioDatagramChannel c) throws Exception {
        log.info("..adding to pipeline..");
        ChannelPipeline pipeline = c.pipeline();
        pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
        pipeline.addLast(new DatagramServerHandler());
    }
}
package net.bounceme.dur.netty.string;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import java.util.logging.Logger;

public class StringServerInitializer extends ChannelInitializer<ServerSocketChannel> {

    private static final Logger log = Logger.getLogger(StringServerInitializer.class.getName());

    public StringServerInitializer() {
        log.info("..initializing..");
    }

    @Override
    protected void initChannel(ServerSocketChannel c) throws Exception {
        log.info("..adding to pipeline..");
        ChannelPipeline pipeline = c.pipeline();
        pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
        pipeline.addLast(new StringDecoder());
        pipeline.addLast(new StringEncoder());
        pipeline.addLast(new StringServerHandler());
    }
}
包net.bounceme.dur.netty.datagram;
导入io.netty.channel.ChannelInitializer;
导入io.netty.channel.ChannelPipeline;
导入io.netty.channel.socket.nio.NioDatagramChannel;
导入io.netty.handler.codec.delimiterBaseFrameDecoder;
导入io.netty.handler.codec.Delimiters;
导入java.util.logging.Logger;
公共类DatagramServerInitializer扩展了ChannelInitializer{
私有静态最终记录器log=Logger.getLogger(DatagramServerInitializer.class.getName());
公共DatagramServer初始值设定项(){
log.info(“…初始化…”);
}
@凌驾
受保护的void initChannel(NioDatagramChannel c)引发异常{
log.info(“…添加到管道…”);
ChannelPipeline=c.管道();
addLast(新的DelimiterBasedFrameDecoder(8192,Delimiters.lineDelimiter());
addLast(新的DatagramServerHandler());
}
}
字符串服务器处理程序:

package net.bounceme.dur.netty.datagram;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;
import java.util.Random;
import java.util.logging.Logger;

public class DatagramServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {

    private static final Logger log = Logger.getLogger(DatagramServerHandler.class.getName());
    private static final Random random = new Random();

    public DatagramServerHandler() {
        log.info("..started..");
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        ctx.writeAndFlush(nextQuote());
    }

    // Quotes from Mohandas K. Gandhi:
    private static final String[] quotes = {
        "Where there is love there is life.",
        "First they ignore you, then they laugh at you, then they fight you, then you win.",
        "Be the change you want to see in the world.",
        "The weak can never forgive. Forgiveness is the attribute of the strong.",};

    private static String nextQuote() {
        int quoteId;
        synchronized (random) {
            quoteId = random.nextInt(quotes.length);
        }
        return quotes[quoteId];
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
        log.info(packet.toString());
        if ("QOTM?".equals(packet.content().toString(CharsetUtil.UTF_8))) {
            ctx.write(new DatagramPacket(
                    Unpooled.copiedBuffer("QOTM: " + nextQuote(), CharsetUtil.UTF_8), packet.sender()));
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.severe(cause.toString());
    }
}
package net.bounceme.dur.netty.string;

import net.bounceme.dur.netty.datagram.DatagramServerHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import java.util.Random;
import java.util.logging.Logger;

public class StringServerHandler extends SimpleChannelInboundHandler<String> {

    private static final Logger log = Logger.getLogger(DatagramServerHandler.class.getName());
    private static final Random random = new Random();

    public StringServerHandler() {
        log.info("..started..");
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        ctx.writeAndFlush(nextQuote());
    }

    // Quotes from Mohandas K. Gandhi:
    private static final String[] quotes = {
        "Where there is love there is life.",
        "First they ignore you, then they laugh at you, then they fight you, then you win.",
        "Be the change you want to see in the world.",
        "The weak can never forgive. Forgiveness is the attribute of the strong.",};

    private static String nextQuote() {
        int quoteId;
        synchronized (random) {
            quoteId = random.nextInt(quotes.length);
        }
        return quotes[quoteId];
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.severe(cause.toString());
    }

    @Override
    protected void channelRead0(ChannelHandlerContext chc, String msg) throws Exception {
        System.err.println(msg);
        if ("QOTM?".equals(msg)) {
            chc.writeAndFlush(nextQuote());
        } else {
            log.warning(msg);  //never executes
        }
    }
}
package net.bounceme.dur.netty.string;
导入net.bounceme.dur.netty.datagram.DatagramServerHandler;
导入io.netty.channel.ChannelHandlerContext;
导入io.netty.channel.SimpleChannelInboundHandler;
导入java.util.Random;
导入java.util.logging.Logger;
公共类StringServerHandler扩展了SimpleChannelInboundHandler{
私有静态最终记录器log=Logger.getLogger(DatagramServerHandler.class.getName());
私有静态最终随机=新随机();
公共StringServerHandler(){
log.info(“…开始…”);
}
@凌驾
公共无效channelActive(ChannelHandlerContext ctx)引发异常{
超级通道激活(ctx);
ctx.writeAndFlush(nextQuote());
}
//莫汉达斯·甘地的名言:
私有静态最终字符串[]引号={
“哪里有爱,哪里就有生命。”,
“首先他们忽视你,然后他们嘲笑你,然后他们和你打架,然后你赢了。”,
“成为你想在世界上看到的改变。”,
“弱者永远不会原谅。原谅是强者的属性。”,};
私有静态字符串nextQuote(){
int quoteId;
同步(随机){
quoteId=random.nextInt(quotes.length);
}
返回引号[quoteId];
}
@凌驾
公共无效channelReadComplete(ChannelHandlerContext ctx){
ctx.flush();
}
@凌驾
公共无效例外情况(ChannelHandlerContext ctx,可丢弃原因){
log.severy(原因.toString());
}
@凌驾
受保护的无效channelRead0(ChannelHandlerContext chc,字符串msg)引发异常{
系统错误打印项次(msg);
如果(“QOTM?”.等于(msg)){
chc.writeAndFlush(nextQuote());
}否则{
log.warning(msg);//从不执行
}
}
}