3

这可能更像是一个讨论而不是一个问题。

背景:
我有两对服务器/客户端,一对用 Java 编写,一对用 C# 编写。两对都在做同样的事情。当我使用 Java\Java 和 C#\C# 组合时没有问题。我想让 Java\C# 和 C#\Java 的组合也能正常工作。I\O 没问题,我使用的是表示 XML 格式字符串的字节数组。我一定会使用 TCP。

我需要关心优雅的断开连接,在 Java 中没有这样的事情。当您关闭客户端的套接字时,服务器端套接字仍处于被动关闭状态 - 因此处理此套接字的服务器线程仍然存在,并且在许多客户端的情况下,我最终可能会得到数千个不必要的线程。在 C# 中,调用 TcpClient.Available 来确定缓冲区中是否有数据或客户端是否已关闭(SocketException)就足够了。在Java中,我可以想到两种方法:

  1. 您必须向套接字的底层流写入一些内容才能真正测试,另一端是否仍然打开。
  2. 您必须让另一方知道,您正在关闭连接的一侧,然后再关闭它。我已经实现了这个,在关闭客户端套接字之前,我将包含 0x04 字节(传输结束)的数据包发送到服务器,服务器通过关闭套接字的服务器端对此字节做出反应。

不幸的是,当涉及到 C#\Java 和 Java\C# 客户端\服务器对时,这两种方法都让我进退两难。如果我希望这些对能够相互通信,我将不得不添加用于将 0x04 字节发送到 C# 客户端的代码,当然还有将其处理到 C# 服务器的代码,这是一种开销。但是我可以忍受不必要的网络流量,主要问题是,这个 C# 代码是核心通信库的一部分,除非绝对必要,否则我不想碰它

问题:
Java 中是否有其他方法可以优雅地断开连接,不需要写入底层套接字流并检查结果,因此我也不必在 C# 代码中处理这个问题?当涉及到使用的库时,我可以自由支配,我不必只使用 Java SE\EE。

4

2 回答 2

2

我在这个答案中对这个“优雅的断开连接”主题给出了(我认为是一个)简明的解释,我希望你觉得它有用。

请记住,双方都必须使用相同的优雅断开模式。我发现自己试图优雅地断开客户端套接字,但服务器一直在发送数据(没有关闭自己的端),这导致了无限循环......

于 2013-04-14T15:50:16.397 回答
0

答案很明显。在 C# 中也没有像优雅断开这样的东西,它是关于 TCP 协议合约的。所以存在与 Java 相同的问题,只是略有不同,您可以在某些情况下解决 -> 如果您通过 NetworkStream 发送 0 个字节然后检查 TcpClient.Connected 状态,它在某种程度上是正确的。然而,从我在互联网上发现的情况来看,这既不可靠也不受欢迎,如何在 C# 中测试连接。当然在我的 C# 库中它已经被使用了。在 Java 中,您根本无法使用它。

所以我在客户端断开连接时向服务器发送“传输结束”数据包的解决方案是可靠的,我也在 C# 库中引入了它。现在我只是害怕出现第一个错误......

最后一点,我还必须实现某种机制,为崩溃的客户端收集服务器上的处理线程。请记住,如果您正在做类似的事情,则没有客户必然会按预期结束;)

于 2013-01-18T10:22:52.840 回答