背景:我正在开发一个客户端-服务器应用程序,尽管经常出现网络问题、中断、管道损坏等问题,但它大部分时间都相当可靠。我使用非阻塞套接字、select() 和 OpenSSL 在集群中的一个或多个节点之间传递消息,具体取决于应用程序级的心跳。消息被排队并且直到整个消息被传输并且所有 SSL_write()s 成功返回后才从队列中删除。我为每个关系维护两个套接字,一个传入和一个传出。我这样做是有原因的,那是因为在写入时检测到失败的连接(非常频繁)比在读取时要容易得多。如果客户端正在连接,并且我已经有连接,我将替换它。基本上,执行写入的客户端负责检测错误并启动新连接(然后将替换服务器上现有的(死)读取连接)。除了一个例外,这对我来说效果很好。
唉,我正在丢失消息。99.9% 的时间,消息都能顺利通过。但时不时地,我会发送,几分钟后我在任何一方都没有检测到错误......然后我会在套接字上收到错误。问题是 SSL_write 已经成功返回。
让我猜猜:如果我阻止这会很好,但由于我是非阻塞的,我不会等待远程端的读取。只要我的 TCP 缓冲区可以容纳更多,我就会一直在管道中填充东西。当我的套接字失效时,我会丢失该缓冲区中尚未交付的任何内容?
我该如何处理?应用程序级别的确认真的有必要吗?(我宁愿不走复杂的丢失确认和重复消息复杂性的漫长道路)有没有一种优雅的方法来知道我丢失了什么消息?或者有什么方法可以延迟从队列中删除,直到我知道它已经交付?(没有ack,怎么办?)
感谢您提前提供任何帮助。