sockets - 为什么 UDP 编写器要拨号?

标签 sockets go udp

我有 C 语言背景,根据我的理解,UDP 是一种无连接协议(protocol),我认为这意味着如果不先建立连接就无法发送数据包。然而,当我进入 Go 并开始编写网络代码时。我意识到 Go 的 UDP 编写器在向主机发送数据包之前先调用主机。这是为什么?

最佳答案

UDP 无连接的,至少在原则上是这样(实现各不相同)。但是还有一个实现细节需要担心:要从“我”(我的 IP 主机和端口地址)向“你”(你的 IP 主机和端口地址)发送一个 UDP 数据包(数据报),我必须至少,指定您的 IP 和端口。如果您想向我发送数据报,则情况相反。

根据底层操作系统,您或我可能能够通过sendto 系统调用来完成此操作。也就是说,我们从 socket 系统调用开始,然后使用 sendto 系统调用进行即发即弃:数据报发送或不发送,然后我们永远不要费心去看看接下来会发生什么。 sendto 调用采用目标地址,对于 TCP 或 UDP,该地址提供 IP 地址和端口。

或者,我们可以使用 socket 系统调用,然后是可选的 bind 系统调用,然后是 connect 系统调用。< sup>1 如果我们这样做,bind 会建立我们的本地端口(可能还有 IP 地址,如果我们有多个)并且 connect 会建立我们的目标 IP 地址和端口。现在我们可以使用 writesend 系统调用发送数据包。

(一些系统添加了 sendmsg 和其他类似的调用,它们通常是上述所有调用的超集,因此可以在没有初步 connect 的情况下使用。但是 所有 支持 TCP 的系统都有创建网络连接和绑定(bind)和或连接然后写入数据的概念。)

一个非常有用的最小公分母设置是假设您将在要创建网络连接时指定您的远程对等地址。要在 Go 中执行此操作,请使用 Dial。即使您的底层系统只有原始 IP 套接字,该库也可以在这些套接字之上构建 UDP 并提供 Dial 接口(interface),然后它仍然可以在 Go 中工作。


1理想情况下,这可能应该是一个“建立对等信息”系统调用,提供本地远程寻址信息,以及任何可选的标志。省略远程说明符将意味着“监听来自所有人的所有传入连接”。这将消除对 SO_REUSEADDR 标志的需要,该标志的存在只是因为无法区分 connect 之前的 bind,或 listen 之前的 bind。但是现在修复 4.2BSD 有点晚了。 😀

关于sockets - 为什么 UDP 编写器要拨号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59059874/

相关文章:

java - 来自 Socket 的 DataInputStream 的 "available"

IOS UI 在套接字连接期间卡住

json - 在 golang 中用数组解析 JSON

c++ - Win32 C++ sendto() 返回错误 8 : WSA_NOT_ENOUGH_MEMORY

自动调用UDP函数

java - 来自 Java UDP 的空指针异常

c - 了解用于接收 UDP 消息和打开 TCP 套接字的 Select 循环

c++ - 线程等待父级

go - 如何在另一个时区获得等效时间

templates - 如何在golang中定义匿名数据结构