网络编程:是否维护套接字?

我目前正在将API从C#转换为具有网络组件的Java。

C#版本似乎在其使用的类的持续时间内保持输入和输出流以及套接字打开。

它是否正确?

请记住,应用程序正在根据用户输入发送命令和接收事件,为每个“消息”打开一个新的套接字流是否更明智?

我正在维护一个ServerSocket来监听服务器抛出事件,但我不太确定为出站通信维护Socket和输出流是个好主意。

我并不习惯Socket编程。 和许多开发人员一样,当我需要进行网络连接时,我通常在应用层工作,而不是在套接字层工作,自从我在大学完成这些工作以来已经有5到6年了。

干杯帮忙。 我想这更需要建议而不是一个明确的答案。

在保持连接开放的成本和创建这些连接的成本之间存在权衡。

创建连接需要花费时间和带宽。 你必须进行3路TCP握手,启动新的服务器线程,……

保持连接开放主要是内存和连接。 网络连接是受OS限制的资源。 如果连接的客户端太多,则可能会耗尽可用的连接。 它会花费内存,因为每个连接都会打开一个线程,并且具有相关的状态。

正确的平衡将根据您期望的用途而有所不同。 如果你有很多客户连接很短的时间,关闭连接可能会更有效率。 如果你很少有客户连接很长一段时间,你应该保持连接打开…

如果您在客户端和服务器上只有一个插槽,则应尽可能长时间保持打开状态。

如果你的应用程序和它所谈到的服务器是接近的,网络方面的,那么关闭连接可能是明智的,但如果它们是远程的,在网络方面,你可能最好让套接字在一段时间内保持活动状态。

Guillaume提到了3次握手,这基本上意味着打开套接字将至少花费最短数据包传输时间的3倍。 这可以通过“ping往返的一半”来近似,并且对于长距离可以容易地达到60-100ms。 如果最终还有300毫秒等待,对于每个命令,是否会影响用户体验?

就个人而言,我会打开套接字,它更容易,并且不需要花费时间用于“需要发送内容”的每个实例,相对成本很小(一个文件描述符,用户空间中的数据结构的一点内存)和内核中的一些额外存储空间)。

这取决于您希望用户输入命令的频率。 如果它很少发生,你可以关闭套接字。 如果频繁,重复创建套接字可能是一项昂贵的操作。

现在已经说过,就机器资源而言,如果要为不频繁的数据打开套接字连接,它有多昂贵? 为什么你认为“为出站通信维护套接字和输出流并不是一个好主意”(尽管这似乎是正确的做法)? 另一方面,如果您希望其他进程可能想要使用同一文件,则文件流会有所不同。 在这种情况下快速关闭文件流将是最佳选择。

您是否有可能用尽您可以创建的许多TCP连接,哪些其他进程可能要使用出站连接? 或者您希望一次有大量客户端连接到您的服务器?

您还可以查看DatagramSocket和DatagramPacket。 优点是低开销,缺点是常规Socket提供的开销。

我建议你看看使用像ActiveMQ或Netty这样的现有消息传递解决方案。 这将处理您可能通过消息传递发现的许多问题。

我来晚了一点,但我没有看到有人这么做。

我认为考虑汇集你的连接(无论是Socket还是TCP)都是明智的,能够保持几个连接打开并在代码库中快速重用它们在性能方面是最佳的。

事实上,Roslyn编译器在很多地方广泛使用这种技术。 https://github.com/dotnet/roslyn/search?l=C%23&q=pooled&type=&utf8=%E2%9C%93