在ServerHandler外部发送时,客户端未收到服务器发送的消息

时间:2015-07-08 06:37:09

标签: java tcp client-server netty

我正在尝试从netty服务器向连接的客户端发送消息。

我想要做的与inversion of control非常相似。 但是,我使用的是 io.netty (带有org.jboss.netty。*包的那个)版本 3.10.0.Final

这就是我所做的:

TelnetServer.java 包含启动服务器的代码。

public static void main(String[] args) throws Exception {
        // Configure SSL.
        final SslContext sslCtx;
        if (SSL) {
            SelfSignedCertificate ssc = new SelfSignedCertificate();
            sslCtx = SslContext.newServerContext(ssc.certificate(),
                    ssc.privateKey());
        } else {
            sslCtx = null;
        }
        // Configure the server.
        ServerBootstrap bootstrap = new ServerBootstrap(
                new NioServerSocketChannelFactory(
                        Executors.newCachedThreadPool(),
                        Executors.newCachedThreadPool()));
        // Configure the pipeline factory.
        bootstrap.setPipelineFactory(new TelnetServerPipelineFactory(sslCtx));
        // Bind and start to accept incoming connections.
        Channel channel = bootstrap.bind(new InetSocketAddress(PORT));
}

TelentServerPipelineFactory.java

import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
import org.jboss.netty.handler.codec.frame.Delimiters;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;
import org.jboss.netty.handler.ssl.SslContext;

import static org.jboss.netty.channel.Channels.*;

/**
 * Creates a newly configured {@link ChannelPipeline} for a new channel.
 */
public class TelnetServerPipelineFactory implements ChannelPipelineFactory {

    private final SslContext sslCtx;

    public TelnetServerPipelineFactory(SslContext sslCtx) {
        this.sslCtx = sslCtx;
    }

    public ChannelPipeline getPipeline() {
        // Create a default pipeline implementation.
        ChannelPipeline pipeline = pipeline();

        if (sslCtx != null) {
            pipeline.addLast("ssl", sslCtx.newHandler());
        }

        // Add the text line codec combination first,
        pipeline.addLast("framer", new DelimiterBasedFrameDecoder(
                8192, Delimiters.lineDelimiter()));
        pipeline.addLast("decoder", new StringDecoder());
        pipeline.addLast("encoder", new StringEncoder());

        // and then business logic.
        pipeline.addLast("handler", new TelnetServerHandler());
        pipeline.addLast("downstream", new TelnetServerOutgoingHandler());
        return pipeline;
    }
}

TelnetServerHandler.java 中,我存储了一个有界限的频道参考:

public class TelnetServerHandler extends SimpleChannelUpstreamHandler {
    private static Channel channel;

    public static Channel getChannel() {
        return channel;
    }
    .
    .
    .
    .
    @Override
    public void channelBound(ChannelHandlerContext ctx, ChannelStateEvent e)
            throws Exception {
        // TODO Auto-generated method stub
        channel = ctx.getChannel();
    }
}

我尝试使用以下代码在TelnetServerHandler之外发送消息:

Scanner scanner = new Scanner(System.in);
System.out.printf("Type message : ");
message = scanner.nextLine();
try{
    if(channel.isWritable()){
        ChannelFuture future = TelnetServerHandler.getChannel().write(message);
        future.sync();
        if(!future.isSuccess()){
            System.out.println("Send failed : " + future.getCause());
        }
    }
}catch (Exception e) {
    e.printStackTrace();
}

它不会打印错误。当我调试时, future.isSucess()返回 true 值。客户端连接到服务器。但是,客户端从未从服务器收到消息。

我在这里错过了什么吗?非常感谢任何帮助。提前致谢! :)

1 个答案:

答案 0 :(得分:2)

我找到了解决方案。

更改:

ChannelFuture future = TelnetServerHandler.getChannel().write(message);

致:

ChannelFuture future = TelnetServerHandler.getChannel().write(message+"\r\n");

This link指出它需要行分隔符,因此解码器将正确读出消息。

希望它有所帮助。 :)