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

Netty TCP套接字输入流

嵇浩然
2023-03-14

Netty TCP Server在端口8000处运行,接收NMEA格式的数据。它使用Marine API库将胡言乱语转换为需要从套接字输入流的有意义的信息。

SentenceReader sentenceReader = new SentenceReader(socket.getInputStream());
sentenceReader.addSentenceListener(new MultiSentenceListener());
sentenceReader.start();

如何获得正在使用的netty服务器端口的输入流?

共有2个答案

姚向晨
2023-03-14

由于InputStream是阻塞的,而netty是一个异步非阻塞API,因此您不容易理解。

慕胡媚
2023-03-14

SentenceReader没有任何方法来接受“流入”数据,但是通过子类化,可以使其接受数据。

SentenceReader的核心使用一个数据读取器作为其数据,通常这个数据读取器是从一个单独的线程本身轮询的,我们可以修改这个结构来获得我们需要的。

首先,我们用自己的类将SentenceReader子类化,为其提供我们想要的适当构造函数和方法,并消除start和stop方法的影响。我们现在提供了null文件(希望未来的版本提供一种直接传递数据读取器的方法)

public class NettySentenceReader extends SentenceReader {
    public NettySentenceReader () {
        super((InputStream)null);
    }

    @Override
    public void start() {
    }

    @Override
    public void stop() {
    }
}

我们现在需要在我们自己的Netty处理程序中实现内部类DataReader的所有功能,以复制相同的行为

public class SentenceReaderHandler extends
         SimpleChannelInboundHandler<String> {
    private SentenceFactory factory;
    private SentenceReader parent;

    public SentenceReaderHandler (SentenceReader parent) {
        this.parent = parent;
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) {
        if(!ctx.channel().isActive())
            return;
        //ActivityMonitor monitor = new ActivityMonitor(parent);
        this.factory = SentenceFactory.getInstance();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        //ActivityMonitor monitor = new ActivityMonitor(parent);
        this.factory = SentenceFactory.getInstance();
    }

    @Override
    // This method will be renamed to `messageReceived` in Netty 5.0.0
    protected void channelRead0(ChannelHandlerContext ctx, String data)
             throws Exception {
        if (SentenceValidator.isValid(data)) {
            monitor.refresh();
            Sentence s = factory.createParser(data);
            parent.fireSentenceEvent(s);
        } else if (!SentenceValidator.isSentence(data)) {
            parent.fireDataEvent(data);
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        //monitor.reset();
        parent.fireReadingStopped();
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) {
        if(!ctx.channel().isActive())
            return;
        //monitor.reset();
        parent.fireReadingStopped();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) {
        parent.handleException("Data read failed", e);
    }
}

最后,我们需要将其整合到一个网络管道中:

SentenceReader reader = new NettySentenceReader();
bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
    private static final StringDecoder DECODER = new StringDecoder();
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
        pipeline.addLast(DECODER);
        pipeline.addLast(new SentenceReaderHandler(reader)); 
    }
});

 类似资料:
  • 问题内容: 我有一个Java应用程序,即Voip。我正在使用一个套接字通过线程同时发送和接收信息。代码如下所示。 我发现的问题是,当我写入输出流时,它在第一次写入时阻塞。我发送的字节数不多。贝娄是我的写代码。 读取声音代码的另一个线程是… 我已经在实际代码中注释了很大一部分,因为我只是想使其正常工作。我的写函数在第一次写时无限期阻塞。这可能是我的线程有问题吗?我唯一的想法是输出和输入流共享我的套接

  • 我试图修复一个java套接字通信错误,服务器不知道输入消息的长度。在当前情况下,服务器测试输入是否完成方法。然而,这种方法并不总是返回正确答案。它会导致读取部分输入。似乎有两种不同的可能性来解决这个问题。 > 客户端应该在发送后关闭其输出流,但这会导致客户端不读取响应,因为输出流关闭时套接字也会关闭。 有没有其他建议,特别是在nio包的帮助下? 非常感谢。

  • 我转向你,在这件事上我一直把头撞在墙上。 我正在做一个小的socket编程,我可以看到当我把它放出来。println(“…”)while循环之前的代码行(in.readLine())它工作正常,但我需要它位于循环内部。 说清楚一点,我没有看到任何错误。我只是看不到此应用程序的客户端显示文本。它看起来好像在工作,但事实并非如此。此外,我也不控制该应用程序的客户端,它由通过TCP连接到此套接字侦听器应

  • 我使用一个具有双向通信的套接字设置了一个客户端-服务器模型。 应该是这样的:1。客户端-发送单词数组2。服务器-读取单词数组3。服务器-发送布尔值4。客户端-读取布尔值5。客户端-发送图像6。服务器读取图像 这个过程在一个循环中,与第一次迭代完美配合,但在第二次迭代中,我得到了以下错误: JAVA网SocketException:软件导致的连接中止:套接字写入错误 我认为发生的是,当服务器返回到读

  • 在用你们的建议编辑我的代码之后,以及将代码压缩到我可以查明导致问题的代码行的位置。服务器代码:' 公共类服务器 2 { } 公共类Client2 { } 服务器输出:-------------------- 服务器已创建。 等待连接... 接受的连接:Socket[addr=/127.0.0.1, port=51565, localport=12362] 正在发送SFileToBeSent。txt

  • 在我的客户端/服务器应用程序中,我的客户端wiil与服务器通信有两个功能:客户端要么向服务器请求数据,要么发送数据,以便服务器保存。我对这两种方法都使用一个套接字,要使用的方法由发送的第一个字节定义。如果第一个字节是“1”,它将请求数据。如果是“2”,它将发送数据(数据字节在“2”字节之后发送)。它非常适合发送数据。但是当我请求数据时,只要我不读取客户端中的套接字流,它就可以工作。这就像如果我在发