2

我正在创建客户端-服务器系统,它应该能够在可用的网络中工作。它假设连接可能一次中断,然后系统必须重新连接并继续工作。我正在使用 Netty 并遇到一个问题:我们怎么知道我们发送的消息被另一台主机接收了?

我在想,为此可以使用 ChannelFuture,如果在附加的未来监听器中失败,我可以简单地尝试再次发送消息:

ChannelFuture fut = channel.write(message);
fut.addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            if (!future.isSuccess()) {
                LOGGER.error("Message send failed. Message: " + message, future.getCause());
                //Queue message to be send after reconnect
            } 
        }
});

但是当我完成后,我注意到,那个监听器从不打印错误。(当系统几乎不工作时,我通过从网络上拔下插头对此进行了测试)此外,我注意到我发送的所有消息期货都进入“完成”状态,并且无法确保收到消息(不使用确认消息)

据我所知,TCP 协议保证该消息会被接收,并且在使用它时,我们可以知道哪些发送包到达了目的地,哪些没有。我不敢相信Netty不允许知道它。

有什么好方法可以知道消息已送达吗?

4

2 回答 2

6

你误解了TCP。TCP 不保证收到您的消息。它提供了一个可靠的、有序的字节流。它对您的消息一无所知,也无法告诉您远程主机何时收到消息。因此,Netty 也不能。Netty 只能告诉你,你的消息在传输之前已经被写入操作系统缓冲区。这就是您的代码正在检测的内容。

为确保您的消息已被接收,接收者必须发回一个明确的确认。实现这一点的最佳方法取决于您的协议的预期行为,但通常涉及维护一个包含所有已发送但尚未确认的消息的表。

于 2013-04-29T16:06:54.483 回答
1

你未来所做的就是将消息写入网络。

要保证接收,您必须实现确认或使用消息编号并重新发送请求。

于 2015-02-07T03:19:55.547 回答