【问题标题】:no-blocking server and thread safe无阻塞服务器和线程安全
【发布时间】:2010-11-12 03:25:27
【问题描述】:

我有一台服务器,它使用一个线程从远程数据源接收 UDP 数据报包;和一个 TCP ServerSocket 来监听远程客户端的请求并为每个客户端生成一个专用线程。 我想通过 ServerSocket 将每个 DatagramPackets 传输到多个客户端。现在我遇到了严重的丢包。有人可以给点建议吗? 提前致谢。

【问题讨论】:

  • 在哪里(在服务器和数据源或服务器和客户端之间)以及您在哪个方向遇到这种严重的数据包丢失?

标签: java multithreading io


【解决方案1】:

这可能只是设计中协议的错误选择吗? 当您使用 TCP 时,应该对多个客户端可靠的东西。但是由于在服务器端引入了对 UDP 槽耦合(桥接/转播)的依赖,可靠性失败了。

UDP 或多或少适用于可靠的应用程序,如果您考虑到数据包会因设计而丢失。

  • 解决方案 1:更改协议
  • 解决方案 2:如果无法更改协议,则更改客户端用户对服务质量的期望
  • 解决方案 3:向 UDP 端添加冗余以重复请求,提前存储数据以防质量下降,无论如何都要保持大量累积的数据缓存以供客户端使用。

【讨论】:

  • 4.重新实现 TCP over UDP O.o
  • 感谢您的回答。恐怕这是多线程编程中典型的生产者-消费者问题。现在我正在努力解决它。任何指导方针表示赞赏。
【解决方案2】:

在发送方摆脱 UDP 会更重要,而不是试图以某种方式将其硬塞到接收方的 TCP 设计中,因为已经太迟了。数据包在发送方和接收方之间丢失,而不是在您的接收方中。修复接收器代码并不能解决实际问题。

【讨论】:

    【解决方案3】:

    在不了解您的应用程序设计的情况下,我可以做出以下猜测:

    • 您的 UDP 源发送的数据包超出了接收器的处理能力,导致数据包被丢弃,因为
    • 在将数据包传递给 TCP 客户端时,您的接收器被阻止,因为
    • 您的 TCP 客户端接收数据包的速度不够快,导致缓冲区填满(这会迫使服务器阻塞,从而导致它错过 UDP 数据包)。

    【讨论】:

    • 感谢您的回答。我已经定位到丢包的原因了,和你说的一样。接收缓冲区由UDP接收线程和TCP发送线程共享,如果发送线程在新数据包到来之前没有完成发送过程,就会导致数据包丢失。我尝试过等待通知机制来安排这些写入和读取线程,但它很容易陷入死锁。由于我没有太多的多线程编程经验,不知道有没有其他的机制。你能给点建议吗?非常感谢!
    • @Xu DXn:尝试使用BlockingQueueConcurrentLinkedQueue 之类的东西。每个 TCP 连接可能有一个队列。但是,您必须处理接收到的 UDP 数据包数量超过一个或多个 TCP 客户端可以处理的可能性,并决定丢弃哪些数据包。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    相关资源
    最近更新 更多