sockets - 为什么 UDP writer 拨号?
问题描述
我来自 C 背景,据我了解,UDP 是一种无连接协议,我认为这意味着如果不先建立连接就无法发送数据包。然而,当我进入 Go 并开始编写网络代码时。我意识到 Go 的 UDP 编写器在向主机发送数据包之前会先拨号。这是为什么?
解决方案
UDP是无连接的,至少在原则上是这样(实现方式不同)。但是还有一个实现细节需要担心:从“我”(我的 IP 主机和端口地址)向“你”(你的 IP 主机和端口地址)发送一个 UDP 数据包(数据报),我必须,至少,指定您的 IP 和端口。如果您想向我发送数据报,则反过来也是如此。
根据底层操作系统,你或我也许sendto
可以通过系统调用来做到这一点。也就是说,我们从一个socket
系统调用开始,然后使用一个sendto
系统调用来一劳永逸:数据报关闭或不关闭,我们从不费心去看看接下来会发生什么。该sendto
调用采用目标地址,对于 TCP 或 UDP,该地址提供 IP 地址和端口。
或者,我们可以使用socket
系统调用,然后是可选的bind
系统调用,然后是connect
系统调用。1 如果bind
我们这样做,则建立我们的本地端口(可能还有 IP 地址,如果我们有多个)并connect
建立我们的目标 IP 地址和端口。write
现在我们可以使用系统调用或send
系统调用发送数据包。
(一些系统 addsendmsg
和其他这样的调用,它们通常是上述所有方法的超集,因此可以在没有初步的情况下使用connect
。但是所有支持 TCP 的系统都有创建网络连接和 bind-and-or-connect- 的概念ing,然后写入数据。)
一个非常有用的最小公分母设置是假设您将在要创建网络连接时指定远程对等地址。要在 Go 中执行此操作,请使用Dial
. 即使你的底层系统只有原始 IP 套接字,库也可以在这些套接字上构建 UDP 并提供Dial
接口,然后它仍然可以在 Go 中工作。
1理想情况下,这可能应该是一个“建立对等信息”系统调用,提供本地和远程寻址信息,以及任何可选标志。省略远程说明符意味着“监听来自所有人的所有传入连接”。那将消除对标志的需要,该SO_REUSEADDR
标志的存在只是因为无法区分 abind
之前的 aconnect
或 abind
之前的 a listen
。但是现在修复 4.2BSD 有点晚了。
推荐阅读
- swift - 文本前的 Swift 感叹号
- excel - 比较 Excel 中的日期并添加一组单元格
- shell - 如果存在则从 ansible playbook 中删除
- vue.js - 使用道具 vuejs + symfony
- python - 读取 CSV 混合字符串和数字
- ruby-on-rails - 无法使用带有 ActiveStorage 图像处理 gem 的变体显示图像
- mysql - shell和node mysql包之间的mysql root密码不同
- java - 似乎不是通用数组的通用数组错误
- java - 使 scnr.nextLine() 忽略 "\n"
- c - 如何使用 malloc() 分配内存来存储字符串数组?