当前位置: 首页 > 知识库问答 >
问题:

Netty(4)同一TCP会话中的客户端服务器通信

呼延化
2023-03-14
    String host = "localhost";
    int port = 9884;
    EventLoopGroup workerGroup = new NioEventLoopGroup();

    try {
        Bootstrap b = new Bootstrap();
        b.group(workerGroup);
        b.channel(NioSocketChannel.class);
        b.option(ChannelOption.SO_KEEPALIVE, true);
        b.handler(new MyChannelPipeline());

        // Start the client.
        ChannelFuture f = b.connect(host, port).sync();

        String line = "line";
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        while (!line.equals("exit")) {
            line = in.readLine();
            if (line == null) {
                break;
            }
        }

        // Wait until the connection is closed.
        f.channel().closeFuture().sync();

    } finally {
        workerGroup.shutdownGracefully();
    }

管道管道:

    @Override
public void initChannel(Channel ch) throws Exception {

    ChannelPipeline channelPipeline = ch.pipeline();

    //Encodes every request send from the client to the server
    channelPipeline.addLast("clientRequestEncoder", new ClientRequestEncoder());

    //Implements channelActive and exceptionCaught
    channelPipeline.addLast("initialRequestHandler", new InitialRequestHandler());

    channelPipeline.addLast("byteArrayDecoder", new ByteArrayDecoder());

    channelPipeline.addLast("serverResponseDecoder", new ServerResponseDecoder());
    channelPipeline.addLast("serverRequestDecoder", new ServerRequestDecoder());

    //Reads the responses from the client requests AND
    //reads the inbound requests from the server - Implements channelRead 
    //and exceptionCaught
    channelPipeline.addLast("myResponseHandler", new MyResponseHandler());


}

问题是,当我将响应刷新到服务器(在MyResponseHandler中)时,会在InitialRequestHandler中捕获exception:

error=java.lang.UnsupportedOperationException:不受支持的消息类型:ServerResponse(应为:ByteBuf,FileRegion)

我不明白为什么响应不被刷新回服务器,而握手请求总是被正确刷新。在write和flush中,我都使用了ChannelFuture和onOperationComplete这个监听器f.addListener(channelFutureListener.fire_exception_on_failure);在失败时触发。

我可以在同一个管道中使用两个处理程序吗?此外,我应该如何激发由用户输入触发的取消注册事件?

共有1个答案

郜联
2023-03-14

我使用一个覆盖channelActive和channelRead的处理程序解决了这个问题,并正确地重新安排了编码器和解码器。我还这样解决了“用户输入触发的注销事件”:

    String line = "line";
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    do {
        logger.info("You typed: " + line + ". Please type 'exit' to terminate the program!");
        line = in.readLine();
    } while (!line.equals("exit"));
    logger.info("You typed: " + line + ". Please wait until the application is successfully shutdown...");

    f.addListener(new ChannelFutureListener() {
        public void operationComplete(ChannelFuture future) throws Exception {
            myChannelPipeline.getMyClientHandler().sendDisconnectRequest(future);
        }
    });

在sendDisconnectReqeust中,我发送最后一个请求,当我得到最后一个响应(在MyHandler的channelRead中)时,我在管道上调用disconnect:

    ChannelPromise cp = new DefaultChannelPromise(ctx.channel());
    ctx.channel().pipeline().disconnect(cp);

然而,我仍然有其他问题的入站请求,从来没有收到我的客户。

 类似资料:
  • 在探索和实现Proact设计模式后,遇到了一个问题,即客户端(“C”客户端)连接在限制后不再接受。开始探索netty。这是我试图做的1。C客户端建立连接2。Java服务器接受连接并开始使用TCP向客户端发送8 Mb大小的字节缓冲区。有什么想法吗?netty是一个好的选择吗?我浏览了netty的一个很好的例子,不幸的是不走运。 先谢谢你。 尊敬的Ravi

  • 似乎服务器拒绝了wireshark输出中的tls协商,但我从代码中看不出原因。它是基于工作的代码,只是它被否决了,因此我用新的API更新。代码是开始。需要使用真实的证书。有人知道为什么服务器发送tcp FIN,ack吗? 我有以下服务器代码: 23 16.856111 sonymobi_7f:55:af intelcor_25:1d:fc ARP 42 10.1.10.100在84:c7:ea:7

  • 我需要在netty中有一个客户机/服务器通信,用于我的项目目的之一。所以我刚开始用一个handsOn来改进,我正在学习netty,我是一个初学者。 我尝试了一个简单的客户端服务器与Netty聊天。 客户端和服务器正在初始化,我可以看到服务器能够获得用于建立连接的客户端管道,但是当客户端发送消息时,它没有进入ServerAdapterHandler的messageReceived部分。下面是我的源代

  • 在本节中,我们将构建一个完整的的 Netty客 户端和服务器。虽然你可能集中在写客户端是浏览器的基于 Web 的服务,接下来你将会获得更完整了解 Netty 的 API 是如何实现客户端和服务器的。 Figure 2.1.Echo client / server 图中显示了连接到服务器的多个并发的客户端。在理论上,客户端可以支持的连接数只受限于使用的 JDK 版本中的制约。 echo(回声)客户端

  • 创建 TCP 客户端 最简单的方法来创建一个 TCP 客户端,使用默认选项如下所示: NetClient client = vertx.createNetClient(); 配置 TCP 客户端 如果你不想使用默认值,则创建TCP 客户端时,通过传入NetClientOptions实例可以配置: NetClientOptions options = new NetClientOptions().s