【问题标题】:Java Sockets - ensure one client connection is served before the othersJava Sockets - 确保一个客户端连接在其他客户端连接之前提供服务
【发布时间】:2011-08-24 17:45:46
【问题描述】:

我有多个客户端 TCP 套接字连接到服务器套接字。这没有什么不寻常的。在这些套接字上,服务器套接字需要处理间歇性的数据。在某些时期,从客户端到服务器的数据流几乎是连续的。

我的问题是我需要确保一个套接字连接上的数据在来自其他套接字连接的数据之前由服务器提供服务。只有在那个“特殊”连接上没有更多数据之后,我才应该从其他客户端读取数据。

现在我有一个每个客户端线程的方法,我认为这不是我的情况的最佳解决方案。具有快速“特殊”连接的东西是一种新要求。所以,现在,我正在寻找在不重写我已经拥有的套接字处理的情况下满足这个要求的方法。

有什么建议吗?非常感谢。

【问题讨论】:

  • 设置线程优先级不能给你这个吗?为普通客户端创建一个具有正常优先级的线程,但为特殊客户端创建一个更高优先级的线程。
  • 是的,我可以这样做,但是这样做,我能保证我总是比其他人先阅读快速连接吗?
  • 你是对的。看看这个 SO 问题 - stackoverflow.com/questions/128039/… 。答案中的链接指向线程调度的 JVM 实现中的一个错误。还有一个参考 Effective Java Programming Guide 可能有线程调度的解决方案。

标签: java multithreading sockets client-server


【解决方案1】:

您必须实施某种调度/服务质量算法。在最简单的形式中,这确实可能只是“只要特殊套接字上有数据,就不要打扰其他套接字”。

这个简单的模型可以通过例如两个列表来实现:

  1. 特殊插座列表
  2. 常规套接字列表。

一个工人读取套接字,并写入一个队列。读取少量字节后,它会检查特殊套接字是否有数据。如果是这样,请先阅读特殊套接字,然后再继续阅读其他套接字。诀窍是以足够小的块读取数据,以便能够足够快地切换,但又不能太小而失去所有效率。这也是 CPU 调度的工作原理。

请记住,只要特殊套接字有数据,就只读取特殊套接字,其他套接字可能根本不会被读取。如果您不希望这样,请考虑使用加权公平排队加权循环等调度算法。

【讨论】:

    【解决方案2】:

    正如@Konerak 所述,您必须实施某种形式的 QoS。

    您可以尝试为您封装它们的消息定义数据类型,然后添加标记以注释某个消息属于某种类型(例如您的特殊套接字)。然后,当服务器收到一条消息时,您可以将消息插入您开始执行的队列中。首先执行所有标有“特殊”(或您要使用的)标记的消息,然后继续处理所有没有标记的消息。队列 (FIFO) 将确保所有消息都在收到时进行处理。请务必查看队列的 Peek 方法 (http://download.oracle.com/javase/1,5.0/docs/api/java/util/Queue.html)。

    这可以作为一种快速修复,只需最少的代码更改,但这可能会引发一系列新问题。即 Memory ,指的是队列的大小,因为在处理特殊消息之前不会删除其他消息。

    您也可以保留 Thread per Client 方法。在只有几个客户端连接的小型环境中这很好,但是当您开始扩展到更大的数量时,您可能需要开始考虑使用 NIO。但正如我所说,两者都是有效的方法,各有优缺点。

    只是一个想法和一些需要考虑的事情。

    【讨论】:

    • 据我所知(也不是很了解),使用蔚来可以指定优惠渠道。但是切换到 NIO 可能需要相当多的代码更改。我说的对吗?
    • 是的,这就是为什么我把它放在底部并试图想出一些可以让您使用当前代码和最小更改进行 QoS 的东西。
    • @ovdsrn '据我所知(而且我不太了解),使用 NIO 你可以指定优惠渠道':不,你不能。此功能是虚构的。
    • 好吧,我没疯,一直在 Google 上寻找“优惠渠道”却找不到...
    • this book关于NIO的章节开头,在论证NIO的必要性时,是这样说的:
    猜你喜欢
    • 1970-01-01
    • 2016-07-06
    • 2020-02-21
    • 2020-07-21
    • 2016-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多