非阻塞 UDP 套接字是否完全冗余?

问题描述 投票:0回答:1

非阻塞 UDP 套接字如何 完全没有意义?

我看不出使用它们比阻塞 UDP 套接字有什么优势,也不明白为什么它们作为一种结构存在。书籍没有解决这个问题。我错过了什么?

结合我的理解

我了解非阻塞 TCP 套接字在编写可伸缩服务器方面的优势。由于 TCP 套接字(阻塞或非阻塞)表示与 single 远程主机的连接,它只能从该主机发送和接收数据。因此,如果您有 1 个线程服务于 1 个以上的连接,即每个线程有 1 个以上的套接字实例,那么如果其中一个阻塞,则其余线程将不会得到服务。所以你需要一个每个连接 1 个线程的模型(即套接字实例),但这不能很好地扩展,因为每个线程都是有代价的(著名的 C10k 问题)。

非阻塞通过让 1 个线程服务于多个 TCP 连接来解决这个问题。用 Java 的说法,选择器能够判断至少一个通道何时准备好进行 IO,并判断哪些通道准备就绪。非阻塞 IO 中的选择器是跨多个 TCP 套接字的多路复用器。

现在,在 UDP 中,

DatagramSocket
已经充当多路复用器。 单个(阻塞的)UDP 套接字可以从任何远程主机接收(和发送)数据报,所以当我这样做时

import java.net.{DatagramPacket, DatagramSocket}

val udpSocket = new DatagramSocket(<some-port>)
def run(): Unit = {
  val packet = new Datagrampacket(new Array[Byte](150), 150)
  udpSocket.receive(packet)
  // datagram contains the source IP and port.
  // do something with the datagram
  run()
}

当我从

ANY
远程UDP套接字接收数据时,阻塞receive将返回。因此,由于 UDP 的性质,只能通过 TCP 中的非阻塞通道/选择器实现的行为可以通过阻塞 UDP 来实现。

这有意义吗?

  1. 如果是这样,为什么我们在Java中也有非阻塞UDP连接的概念?他们增加了什么价值?
  2. 我想底层操作系统也有那个构造?为什么?
java sockets networking tcp udp
1个回答
2
投票

当我从任何远程 UDP 套接字接收数据时,阻塞接收将返回。

未绑定的 UDP 套接字将从任何远程 UDP 套接字接收数据 - 只要它是针对本地套接字绑定到的特定 IP 和端口。所以,如果你想在你的应用程序中有多个具有不同端口的 UDP 端点,你需要为此创建多个套接字。一个常见的用例是 SIP、H.323、WebRTC 中的实时音频和视频……其中每个媒体通道通常使用不同的端口。

除此之外,实际绑定 UDP 套接字也很有用,这样一个套接字仅从特定的远程端点接收数据。这可以使编程更容易,但也可以通过消除单套接字瓶颈来帮助扩展应用程序。

© www.soinside.com 2019 - 2024. All rights reserved.